From 9bc63da27b6aaa3c44e57b80337993d6a2368af6 Mon Sep 17 00:00:00 2001 From: dulingling Date: Wed, 22 Apr 2020 11:50:17 +0800 Subject: [PATCH 01/40] =?UTF-8?q?Upd:=E5=95=86=E6=88=B7=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0IT=E8=81=94=E7=B3=BB=E4=BA=BA=E9=82=AE?= =?UTF-8?q?=E7=AE=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manage/merchants/beans/ClientRegisterInfo.java | 10 ++++++++++ .../payment/partner/templates/add_partner.html | 10 ++++++++++ .../payment/partner/templates/partner_detail.html | 10 ++++++++++ .../payment/partner/templates/partner_edit.html | 12 +++++++++++- 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientRegisterInfo.java b/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientRegisterInfo.java index 5a961a42b..8ccdcc9c3 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientRegisterInfo.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientRegisterInfo.java @@ -112,6 +112,8 @@ public class ClientRegisterInfo { private String client_pay_type; @NotEmpty(message = "error.payment.valid.param_missing") private String client_pay_desc; + @JSONField(name = "it_contact_person_email") + private String itContactPersonEmail; public JSONObject insertObject() { JSONObject res = (JSONObject) JSON.toJSON(this); @@ -550,4 +552,12 @@ public class ClientRegisterInfo { public void setMarketingWechatId(String marketingWechatId) { this.marketingWechatId = marketingWechatId; } + + public String getItContactPersonEmail() { + return itContactPersonEmail; + } + + public void setItContactPersonEmail(String itContactPersonEmail) { + this.itContactPersonEmail = itContactPersonEmail; + } } diff --git a/src/main/ui/static/payment/partner/templates/add_partner.html b/src/main/ui/static/payment/partner/templates/add_partner.html index 1bec9f8b7..6ebd8ff88 100644 --- a/src/main/ui/static/payment/partner/templates/add_partner.html +++ b/src/main/ui/static/payment/partner/templates/add_partner.html @@ -669,6 +669,16 @@ Characters(including symbols and spaces)

+ +
+ +
+ +
+
+ +
+ +
+ +
+
+
diff --git a/src/main/ui/static/payment/partner/templates/partner_edit.html b/src/main/ui/static/payment/partner/templates/partner_edit.html index 2c2a33896..d9a07d714 100644 --- a/src/main/ui/static/payment/partner/templates/partner_edit.html +++ b/src/main/ui/static/payment/partner/templates/partner_edit.html @@ -578,7 +578,16 @@ Characters(including symbols and spaces)

- + +
+ +
+ +
+
+
From 0f7f855ffad0b5995d3d19126974edb5674033ac Mon Sep 17 00:00:00 2001 From: dulingling Date: Wed, 22 Apr 2020 13:48:17 +0800 Subject: [PATCH 02/40] =?UTF-8?q?Upd:=E5=95=86=E6=88=B7=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0IT=E8=81=94=E7=B3=BB=E4=BA=BA=E9=82=AE?= =?UTF-8?q?=E7=AE=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../partner/templates/client_partner_detail.html | 10 +++++++++- .../payment/partner/templates/client_partner_edit.html | 9 +++++++++ .../payment/partner/templates/partner_detail.html | 6 +++--- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/main/ui/static/payment/partner/templates/client_partner_detail.html b/src/main/ui/static/payment/partner/templates/client_partner_detail.html index 2a1f185f7..e13c7127f 100644 --- a/src/main/ui/static/payment/partner/templates/client_partner_detail.html +++ b/src/main/ui/static/payment/partner/templates/client_partner_detail.html @@ -390,9 +390,17 @@
+ +
+ +
+

+ +

+
+
-

diff --git a/src/main/ui/static/payment/partner/templates/client_partner_edit.html b/src/main/ui/static/payment/partner/templates/client_partner_edit.html index 7cb3edb4f..40b9b1cbf 100644 --- a/src/main/ui/static/payment/partner/templates/client_partner_edit.html +++ b/src/main/ui/static/payment/partner/templates/client_partner_edit.html @@ -392,6 +392,15 @@ Characters(including symbols and spaces)

+ +
+ +
+ +
+
+ +
+
Card Payment Config
+
+
+ +
+ +
+ +
+
+
+
+
+
Retail In Store Payment(App, WePayLite, Albert)
From 42ec49784d1f142e2c7297195082b6b2c135fb5f Mon Sep 17 00:00:00 2001 From: dulingling Date: Fri, 24 Apr 2020 15:21:35 +0800 Subject: [PATCH 05/40] =?UTF-8?q?Upd:=E8=A1=A5=E5=85=85=E5=8D=A1=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E6=B8=A0=E9=81=93=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/impls/RetailAppServiceImp.java | 8 +++++++- src/main/resources/application-common.yml | 2 +- src/main/resources/application-dev.yml | 16 ++++++++-------- src/main/resources/application.yml | 14 +++++++------- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/RetailAppServiceImp.java b/src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/RetailAppServiceImp.java index 19e4fc2f2..c919abc30 100644 --- a/src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/RetailAppServiceImp.java +++ b/src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/RetailAppServiceImp.java @@ -289,6 +289,12 @@ public class RetailAppServiceImp implements RetailAppService { res.put("rate", paymentApi.channelApi("Wechat").queryExchangeRateDecimal(clientId)); res.put("alipay_rate", paymentApi.channelApi("Alipay").queryExchangeRateDecimal(clientId)); } + params.put("channel", "system"); + res.put("sys_not_settled", new BigDecimal(transactionAnalysisMapper.analysisNotSettled(params))); + params.put("channel", "rpaypmt_card"); + res.put("rpaypmt_card_not_settled", new BigDecimal(transactionAnalysisMapper.analysisNotSettled(params))); + params.put("channel", "rpaypmt_dd"); + res.put("rpaypmt_dd_not_settled", new BigDecimal(transactionAnalysisMapper.analysisNotSettled(params))); return res; } @@ -864,7 +870,7 @@ public class RetailAppServiceImp implements RetailAppService { String clientType = device.getString("client_type"); deviceSupport.findRegister(clientType); int clientId = device.getIntValue("client_id"); - JSONObject client = clientManager.getClientInfo(clientId); + JSONObject client = clientManager.getClientInfo(9); String timezoneClient = client.getString("timezone"); if (timezoneClient != null && !timezone.isEmpty()) { timezone = timezoneClient; diff --git a/src/main/resources/application-common.yml b/src/main/resources/application-common.yml index 238e4f272..f508af2eb 100644 --- a/src/main/resources/application-common.yml +++ b/src/main/resources/application-common.yml @@ -64,7 +64,7 @@ spring: time-between-eviction-runs-millis: 500 validation-query: select 1 mail: - host: smtp.office365.com + host: smtp.o11ffice365.com port: 587 thymeleaf: mode: HTML diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 3beef053f..8952c6aee 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -1,15 +1,15 @@ spring: datasource: master: - host: 192.168.0.84:3306 + host: 119.28.3.196:3310 jdbc-url: jdbc:mysql://${spring.datasource.master.host}/${spring.datasource.master.schema-name}?useUnicode=true&characterEncoding=utf8&useSSL=false - password: rpayplus - schema-name: royalpay - username: root + password: read0nly + schema-name: royalpay_production + username: readonly slave: - host: 192.168.0.84:3306 + host: 119.28.3.196:3310 jdbc-url: jdbc:mysql://${spring.datasource.slave.host}/${spring.datasource.slave.schema-name}?useUnicode=true&characterEncoding=utf8&useSSL=false - password: rpayplus - schema-name: royalpay - username: root + password: read0nly + schema-name: royalpay_production + username: readonly type: com.zaxxer.hikari.HikariDataSource diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 91c8f2a2f..0bde059ef 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -17,7 +17,7 @@ app: cms: host: http://127.0.0.1:9533 customer: - host: https://customer.royalpay.com.au/ + host: http://192.168.0.33:9008/ foreign-currency: AUD hanyin-secure: pid: ROYALPAY @@ -26,10 +26,10 @@ app: sftp-pwd: royalpay sftp-username: royalpay host: - main: http://192.168.0.8:9009/ + main: http://192.168.0.33:9009/ regions: - au: http://192.168.0.8:9009/ - cn: http://192.168.0.8:9009/ + au: http://192.168.0.33:9009/ + cn: http://192.168.0.33:9009/ mail: appid: 1 host: https://mailsupport.royalpay.com.au @@ -114,7 +114,7 @@ royalpay: appkey: 43390d81e20c5191c278fbf4cd275be2 server: - port: 5000 + port: 5555 settle: abafile: @@ -143,8 +143,8 @@ settle: remains-to: ANZ spring: mail: - host: smtp.office365.com - port: 587 + host: '' + port: '' profiles: active: dev,alipay,bestpay,jd,wechat,rpay,yeepay,rppaysvc,common redis: From cb08cd7546fb981376a03acb0e6a6e3be2cca28b Mon Sep 17 00:00:00 2001 From: luoyang Date: Sun, 26 Apr 2020 11:03:33 +0800 Subject: [PATCH 06/40] add customer_rage_title --- .../manage/appclient/core/impls/RetailAppServiceImp.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/RetailAppServiceImp.java b/src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/RetailAppServiceImp.java index c919abc30..9ca43cbfb 100644 --- a/src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/RetailAppServiceImp.java +++ b/src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/RetailAppServiceImp.java @@ -3116,6 +3116,10 @@ public class RetailAppServiceImp implements RetailAppService { channels.add(cbBankPay); } res.put("channels", channels); + if (res.containsKey("rate_value")) { + BigDecimal minRate = res.getBigDecimal("rate_value").add(new BigDecimal(0.01)).setScale(2, RoundingMode.DOWN); + res.put("customer_rage_title", (minRate.toPlainString() + "~" + res.getString("max_customer_surcharge_rate"))); + } return res; } From db974f69e22a3ef0b01f7221506a6e35ddb466f2 Mon Sep 17 00:00:00 2001 From: luoyang Date: Sun, 26 Apr 2020 17:43:46 +0800 Subject: [PATCH 07/40] =?UTF-8?q?add=20=E5=8D=A1=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E5=95=86=E6=88=B7=E8=BF=9B=E4=BB=B6=E3=80=81=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E3=80=81=E5=90=88=E8=A7=84=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../system/SysClientUpayProfileMapper.java | 19 + .../merchants/beans/ClientRegisterInfo.java | 69 + .../core/impls/ClientManagerImpl.java | 69 +- src/main/resources/application-dev.yml | 16 +- src/main/ui/static/commons/commons.js | 1 + .../commons/services/upayIndustryMap.js | 81 ++ .../ui/static/payment/partner/add-partner.js | 884 ++++++++++++ .../static/payment/partner/partner-manage.js | 1239 +++-------------- .../partner/templates/add_partner.html | 333 ++--- .../partner/templates/partner_auth_files.html | 374 +---- .../templates/partner_cp_auth_files.html | 363 +++++ .../partner/templates/partner_detail.html | 3 - .../partner/templates/partner_edit.html | 247 ++-- .../templates/partner_mw_auth_files.html | 274 ++-- 15 files changed, 2092 insertions(+), 1882 deletions(-) create mode 100644 src/main/java/au/com/royalpay/payment/manage/mappers/system/SysClientUpayProfileMapper.java create mode 100644 src/main/ui/static/commons/services/upayIndustryMap.js create mode 100644 src/main/ui/static/payment/partner/add-partner.js create mode 100644 src/main/ui/static/payment/partner/templates/partner_cp_auth_files.html diff --git a/pom.xml b/pom.xml index 19eca1053..4e24bd556 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ au.com.royalpay.payment payment-parent - 2.1.26 + 2.1.28 4.0.0 manage diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/system/SysClientUpayProfileMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/system/SysClientUpayProfileMapper.java new file mode 100644 index 000000000..2e9842a40 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/system/SysClientUpayProfileMapper.java @@ -0,0 +1,19 @@ +package au.com.royalpay.payment.manage.mappers.system; + +import com.alibaba.fastjson.JSONObject; +import com.yixsoft.support.mybatis.autosql.annotations.AutoMapper; +import com.yixsoft.support.mybatis.autosql.annotations.AutoSql; +import com.yixsoft.support.mybatis.autosql.annotations.SqlType; +import org.apache.ibatis.annotations.Param; + +@AutoMapper(tablename = "sys_client_upay_profile", pkName = "client_id") +public interface SysClientUpayProfileMapper { + @AutoSql(SqlType.INSERT) + void save(JSONObject info); + + @AutoSql(SqlType.UPDATE) + void update(JSONObject info); + + @AutoSql(SqlType.SELECT) + JSONObject findInfo(@Param("client_id") int clientId); +} diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientRegisterInfo.java b/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientRegisterInfo.java index 8ccdcc9c3..e6d7d0dbe 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientRegisterInfo.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientRegisterInfo.java @@ -3,6 +3,7 @@ package au.com.royalpay.payment.manage.merchants.beans; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.annotation.JSONField; +import org.apache.commons.lang3.StringUtils; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; @@ -114,8 +115,24 @@ public class ClientRegisterInfo { private String client_pay_desc; @JSONField(name = "it_contact_person_email") private String itContactPersonEmail; + @JSONField(name = "client_type") + private String clientType; + @JSONField(name = "acceptor_name") + private String acceptorName; + @JSONField(name = "expected_card_revenue") + private String expectCardRevenue; + @JSONField(name = "average_card_transaction") + private String averageCardTransaction; + @JSONField(name = "mw_industry") + private String mwIndustry; + @JSONField(name = "enable_international_card") + private boolean enableInternaltionCard; + public JSONObject insertObject() { + if (industry == null) { + setIndustry("331"); + } JSONObject res = (JSONObject) JSON.toJSON(this); if (client_apply_id==null){ res.remove("client_apply_id"); @@ -123,6 +140,10 @@ public class ClientRegisterInfo { return res; } + public boolean enableCardPayment() { + return StringUtils.equalsIgnoreCase("card-payment", clientType) || StringUtils.equalsIgnoreCase("all", clientType); + } + public JSONObject updateObject() { JSONObject obj = insertObject(); obj.remove("client_moniker"); @@ -560,4 +581,52 @@ public class ClientRegisterInfo { public void setItContactPersonEmail(String itContactPersonEmail) { this.itContactPersonEmail = itContactPersonEmail; } + + public void setAcceptorName(String acceptorName) { + this.acceptorName = acceptorName; + } + + public String getAcceptorName() { + return acceptorName; + } + + public boolean isEnableInternaltionCard() { + return enableInternaltionCard; + } + + public String getAverageCardTransaction() { + return averageCardTransaction; + } + + public String getExpectCardRevenue() { + return expectCardRevenue; + } + + public String getMwIndustry() { + return mwIndustry; + } + + public void setAverageCardTransaction(String averageCardTransaction) { + this.averageCardTransaction = averageCardTransaction; + } + + public void setEnableInternaltionCard(boolean enableInternaltionCard) { + this.enableInternaltionCard = enableInternaltionCard; + } + + public void setExpectCardRevenue(String expectCardRevenue) { + this.expectCardRevenue = expectCardRevenue; + } + + public void setMwIndustry(String mwIndustry) { + this.mwIndustry = mwIndustry; + } + + public String getClientType() { + return clientType; + } + + public void setClientType(String clientType) { + this.clientType = clientType; + } } diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index 3edd05647..b77ff85ce 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -326,8 +326,8 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid private RPayPaymentCardSvcApi rPayPaymentCardSvcApi; @Resource private RPayMerchantMapper rPayMerchantMapper; - - + @Resource + private SysClientUpayProfileMapper sysClientUpayProfileMapper; @Resource private SmsSender smsSender; private static final String SOURCE_AGREE_FILE = "source_agree_file"; @@ -433,6 +433,8 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid clientConfig.put("ext_params",client.getString("ext_params")); } client.putAll(clientConfig); + JSONObject upayInfo = sysClientUpayProfileMapper.findInfo(client.getIntValue("client_id")); + client.putAll(upayInfo); client.put("unsubscribe", mailUnsubMapper.findOneByClientMoniker(clientMoniker) == null ? false : true); client.put("show_all_permission", true); int role = manager != null ? manager.getIntValue("role") : 0; @@ -782,10 +784,6 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid partner.put("ali_sub_merchant_id", registery.getClientMoniker()); partner.put("credential_code", RandomStringUtils.random(32, true, true)); partner.put("creator", manager.getString("manager_id")); - // if (manager.getIntValue("org_id") == 0) { - // throw new ForbiddenException("You were not belong to any organizations so that you cannot create new - // client"); - // } partner.put("org_id", manager.getIntValue("org_id")); if (StringUtils.isNotEmpty(registery.getLogoId())) { partner.put("logo_url", attachmentClient.getFileUrl(registery.getLogoId())); @@ -807,7 +805,6 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid //isRiskyMerchant(partner, null); try { - clientMapper.save(partner); JSONObject clientConfig = new JSONObject(); clientConfig.put("client_id", partner.getIntValue("client_id")); @@ -817,33 +814,13 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid clientConfigService.save(clientConfig); permissionPartnerManagerImpl.permissionClientModuleSave(partner.getIntValue("client_id"), partner.getString("client_moniker")); + saveLegalAndMarketingInfo(partner); + if (registery.enableCardPayment()) { + sysClientUpayProfileMapper.save(partner); + } } catch (Exception e) { throw new BadRequestException("error.partner.valid.dumplicate_client_moniker"); } - - try { - JSONObject representativeInfo = new JSONObject(); - representativeInfo.put("client_id", partner.getIntValue("client_id")); - representativeInfo.put("representative_person", partner.getString("legal_representative_person")); - representativeInfo.put("phone", partner.getString("legal_representative_phone")); - representativeInfo.put("email", partner.getString("legal_representative_email")); - representativeInfo.put("job_title", partner.getString("legal_representative_job")); - representativeInfo.put("address", partner.getString("registered_address")); - representativeInfo.put("suburb", partner.getString("registered_suburb")); - representativeInfo.put("postcode", partner.getString("registered_postcode")); - representativeInfo.put("state", partner.getString("registered_state")); - representativeInfo.put("legal_representative_wechatid", partner.getString("legal_representative_wechatid")); -// marking联系人 - representativeInfo.put("marketing_person", partner.getString("marketing_person")); - representativeInfo.put("marketing_phone", partner.getString("marketing_phone")); - representativeInfo.put("marketing_email", partner.getString("marketing_email")); - representativeInfo.put("marketing_job_title", partner.getString("marketing_job")); - representativeInfo.put("marketing_wechatid", partner.getString("marketing_wechatid")); - sysClientLegalPersonMapper.save(representativeInfo); - } catch (Exception e) { - throw new BadRequestException("error.partner.valid.dumplicate_client_moniker"); - } - if (ManagerRole.BD_USER.hasRole(manager.getIntValue("role"))) { JSONObject client_bd = new JSONObject(); client_bd.put("client_id", partner.getIntValue("client_id")); @@ -917,6 +894,16 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid sysClientLegalPersonMapper.save(representativeInfo); } + if (info.enableCardPayment()) { + JSONObject upay = sysClientUpayProfileMapper.findInfo(clientId); + if (upay == null) { + sysClientUpayProfileMapper.save(updateInfo); + }else { + upay.putAll(updateInfo); + sysClientUpayProfileMapper.update(upay); + } + } + int originReferrerId = client.getIntValue("referrer_id"); int updateReferrerId = Integer.parseInt(info.getReferrer_id() == null ? "0" : info.getReferrer_id()); if (originReferrerId == 0 && updateReferrerId != 0) { @@ -7128,4 +7115,24 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid return day+" "+ months[month]+" "+ year; } + public void saveLegalAndMarketingInfo(JSONObject partner) { + JSONObject representativeInfo = new JSONObject(); + representativeInfo.put("client_id", partner.getIntValue("client_id")); + representativeInfo.put("representative_person", partner.getString("legal_representative_person")); + representativeInfo.put("phone", partner.getString("legal_representative_phone")); + representativeInfo.put("email", partner.getString("legal_representative_email")); + representativeInfo.put("job_title", partner.getString("legal_representative_job")); + representativeInfo.put("address", partner.getString("registered_address")); + representativeInfo.put("suburb", partner.getString("registered_suburb")); + representativeInfo.put("postcode", partner.getString("registered_postcode")); + representativeInfo.put("state", partner.getString("registered_state")); + representativeInfo.put("legal_representative_wechatid", partner.getString("legal_representative_wechatid")); + representativeInfo.put("marketing_person", partner.getString("marketing_person")); + representativeInfo.put("marketing_phone", partner.getString("marketing_phone")); + representativeInfo.put("marketing_email", partner.getString("marketing_email")); + representativeInfo.put("marketing_job_title", partner.getString("marketing_job")); + representativeInfo.put("marketing_wechatid", partner.getString("marketing_wechatid")); + sysClientLegalPersonMapper.save(representativeInfo); + } + } diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 8952c6aee..3beef053f 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -1,15 +1,15 @@ spring: datasource: master: - host: 119.28.3.196:3310 + host: 192.168.0.84:3306 jdbc-url: jdbc:mysql://${spring.datasource.master.host}/${spring.datasource.master.schema-name}?useUnicode=true&characterEncoding=utf8&useSSL=false - password: read0nly - schema-name: royalpay_production - username: readonly + password: rpayplus + schema-name: royalpay + username: root slave: - host: 119.28.3.196:3310 + host: 192.168.0.84:3306 jdbc-url: jdbc:mysql://${spring.datasource.slave.host}/${spring.datasource.slave.schema-name}?useUnicode=true&characterEncoding=utf8&useSSL=false - password: read0nly - schema-name: royalpay_production - username: readonly + password: rpayplus + schema-name: royalpay + username: root type: com.zaxxer.hikari.HikariDataSource diff --git a/src/main/ui/static/commons/commons.js b/src/main/ui/static/commons/commons.js index 1f764d66c..51e7b3204 100644 --- a/src/main/ui/static/commons/commons.js +++ b/src/main/ui/static/commons/commons.js @@ -13,6 +13,7 @@ define(['./app', './services/yeepayIndustryMap', './services/stateMap', './services/industryMap', + './services/upayIndustryMap', './services/wechatGoodMcc', './services/sectorMap', './services/countryMap', diff --git a/src/main/ui/static/commons/services/upayIndustryMap.js b/src/main/ui/static/commons/services/upayIndustryMap.js new file mode 100644 index 000000000..ebc3c6cfb --- /dev/null +++ b/src/main/ui/static/commons/services/upayIndustryMap.js @@ -0,0 +1,81 @@ +define(['../app'], function (app) { + 'use strict'; + + var upayIndustry = [ + { + "label": "Professional Services", + "value": "Professional Services" + }, + { + "label": "Mail/Telephone Order", + "value": "Mail/Telephone Order" + }, + { + "label": "Business Services", + "value": "Business Services" + }, + { + "label": "Retail Store", + "value": "Retail Store" + }, + { + "label": "Airline Services", + "value": "Airline Services" + }, + { + "label": "Entertainment", + "value": "Entertainment" + }, + { + "label": "Automobiles", + "value": "Automobiles" + }, + { + "label": "Clothing", + "value": "Clothing" + }, + { + "label": "Contracted Services", + "value": "Contracted Services" + }, + { + "label": "Government", + "value": "Government" + }, + { + "label": "Hotel", + "value": "Hotel" + }, + { + "label": "Personal Services", + "value": "Personal Services" + }, + { + "label": "Repair Services", + "value": "Repair Services" + }, + { + "label": "Transportation", + "value": "Transportation" + }, + { + "label": "Utilities", + "value": "Utilities" + }, + { + "label": "Wholesale", + "value": "Wholesale" + }, + { + "label": "Other", + "value": "Other" + } + ]; + app.factory('upayIndustryMap', function () { + return { + configs: function () { + return upayIndustry; + } + } + }); +}); diff --git a/src/main/ui/static/payment/partner/add-partner.js b/src/main/ui/static/payment/partner/add-partner.js new file mode 100644 index 000000000..8f2e8ae34 --- /dev/null +++ b/src/main/ui/static/payment/partner/add-partner.js @@ -0,0 +1,884 @@ +/** + * Created by yixian on 2016-06-29. + */ +define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter', 'ngBootSwitch', 'ngFileUpload', 'uiSelect'], function (angular, Decimal) { + 'use strict'; + var removeClientPayDesc = function (items, key) { + for (var i = 0; i < items.length; i++) { + var item = items[i]; + if (item.indexOf(key) >= 0) { + items.splice(items.indexOf(item), 1); + i = i - 1; + } + } + }; + + + var app = angular.module('addPartnerApp', ['ui.bootstrap', 'ui.router', 'frapontillo.bootstrap-switch', 'ui.select', 'ngFileUpload']); + app.config(['$stateProvider', function ($stateProvider) { + $stateProvider.state('newPartners', { + url: '/partners/new', + templateUrl: '/static/payment/partner/templates/add_partner.html', + controller: 'addPartnerCtrl' + }).state('partners.edit', { + url: '/{clientMoniker}/edit', + templateUrl: '/static/payment/partner/templates/partner_edit.html', + controller: 'partnerEditCtrl', + resolve: { + partner: ['$http', '$stateParams', function ($http, $stateParams) { + return $http.get('/sys/partners/' + $stateParams.clientMoniker); + }] + } + }) + }]); + app.controller('addPartnerCtrl', ['$rootScope', '$scope', '$http', '$state', 'Upload', 'commonDialog', 'timezone', 'businessStructuresMap', 'upayIndustryMap', 'industryMap', 'stateMap', 'sectorMap', 'countryMap', function ($rootScope, $scope, $http, $state, Upload, commonDialog, timezone, businessStructuresMap, upayIndustryMap, industryMap, stateMap, sectorMap, countryMap) { + if ($scope.partner_application) { + $scope.partner = angular.copy($scope.partner_application); + delete $rootScope.partner_application; + } else { + $scope.partner = {timezone: 'Australia/Melbourne'}; + } + $scope.partner.client_type = 'cross-border'; + $scope.initMerchantCode = function () { + $http.get('/sys/partners/init/merchant_code').then(function (response) { + $scope.partner.client_moniker = response.data.partner_code; + $scope.merchantCodeChecked = true; + $scope.merchantIsValid = true; + }); + }; + $scope.initMerchantCode(); + $scope.partner.company_phone_c = 61; + $scope.partner.contact_phone_c = 61; + $scope.partner.client_pay_type = []; + $scope.partner.client_pay_desc = []; + var resetClientPayDescByTpey = function (type) { + type = parseInt(type); + if (type == 1) { + removeClientPayDesc($scope.partner.client_pay_desc, '10'); + } + if (type == 2) { + removeClientPayDesc($scope.partner.client_pay_desc, '20'); + } + }; + $scope.partner.sameAsContactPerson = false; + $scope.checkboxOnclick = function (){ + $scope.partner.sameAsContactPerson = !($scope.partner.sameAsContactPerson); + if($scope.partner.sameAsContactPerson) { + $scope.partner.legal_representative_person = $scope.partner.contact_person; + $scope.partner.legal_representative_phone_a = $scope.partner.contact_phone_a; + $scope.partner.legal_representative_phone_c = $scope.partner.contact_phone_c; + $scope.partner.legal_representative_phone_p = $scope.partner.contact_phone_p; + $scope.partner.legal_representative_email = $scope.partner.contact_email; + $scope.partner.legal_representative_job = $scope.partner.contact_job; + $scope.partner.legal_representative_wechatid = $scope.partner.contact_wechatid; + } + } + + $scope.partner.marketingSameAsContact = false; + $scope.checkMarketingSameAsContact = function (){ + $scope.partner.marketingSameAsContact = !($scope.partner.marketingSameAsContact); + if($scope.partner.marketingSameAsContact) { + $scope.partner.marketing_person = $scope.partner.contact_person; + $scope.partner.marketing_phone_a = $scope.partner.contact_phone_a; + $scope.partner.marketing_phone_c = $scope.partner.contact_phone_c; + $scope.partner.marketing_phone_p = $scope.partner.contact_phone_p; + $scope.partner.marketing_email = $scope.partner.contact_email; + $scope.partner.marketing_job = $scope.partner.contact_job; + $scope.partner.marketing_wechatid = $scope.partner.contact_wechatid; + } + } + + $scope.partner.sameAsAddress=false; + $scope.sameAddress = function (){ + $scope.partner.sameAsAddress = !($scope.partner.sameAsAddress); + if($scope.partner.sameAsAddress) { + $scope.partner.registered_address = $scope.partner.address; + $scope.partner.registered_suburb = $scope.partner.suburb; + $scope.partner.registered_postcode = $scope.partner.postcode; + $scope.partner.registered_state = $scope.partner.state; + } + } + + var compare = function (x, y) { + x = parseInt(x); + y = parseInt(y); + if (x < y) { + return -1; + } else if (x > y) { + return 1; + } else { + return 0; + } + } + $scope.toggleClientPayType = function (type) { + if ($scope.partner.client_pay_type == null || $scope.partner.client_pay_type == undefined) { + $scope.partner.client_pay_type = []; + } + var $idx = $scope.partner.client_pay_type.indexOf(type); + if ($idx >= 0) { + $scope.partner.client_pay_type.splice($idx, 1); + resetClientPayDescByTpey(type); + } else { + $scope.partner.client_pay_type.push(type); + $scope.partner.client_pay_type.sort(compare); + } + }; + $scope.toggleClientPayDesc = function (type) { + if ($scope.partner.client_pay_desc == null || $scope.partner.client_pay_desc == undefined) { + $scope.partner.client_pay_desc = []; + } + var $idx = $scope.partner.client_pay_desc.indexOf(type); + if ($idx >= 0) { + if (type == '203') { + removeClientPayDesc($scope.partner.client_pay_desc, '2030') + } + $scope.partner.client_pay_desc.splice($idx, 1); + } else { + $scope.partner.client_pay_desc.push(type); + $scope.partner.client_pay_desc.sort(compare); + } + }; + $scope.pagination = {}; + $scope.industries = industryMap.configs(); + $scope.upayIndustrys = upayIndustryMap.configs(); + $scope.states = stateMap.configs(); + $scope.countries = countryMap.configs(); + $scope.sectors = sectorMap.configs(); + $scope.business_structures = businessStructuresMap.configs(); + $scope.params = {textType: 'all', org_name: 'ALL'}; + $scope.merchantIsValid = false; + $scope.merchantCodeChecked = false; + + function remove(arr, val) { + if (angular.isArray(arr)) { + for (var i = arr.length; i--;) { + if (arr[i].value == val) { + arr.splice(i, 1); + break; + } + } + } + return arr; + } + + var industries = angular.copy($scope.industries); + $scope.industries = remove(industries, 331); + + $scope.listReferrers = function () { + $http.get('/sys/orgs/referrer').then(function (resp) { + $scope.referrers = resp.data; + }) + }; + $scope.listReferrers(); + + $scope.loadAlipayCategory = function () { + $http.get('/static/data/alipayMcc.json').then(function (resp) { + $scope.alipayMccCategory = resp.data; + }) + }; + $scope.loadAlipayCategory(); + $scope.loadJDindustry = function () { + $http.get('/static/data/jdindustry.json').then(function (resp) { + $scope.jdindustry = resp.data; + }) + }; + $scope.loadJDindustry(); + + $scope.loadLakalaPayindustry = function () { + $http.get('/static/data/lakalapayindustry.json').then(function (resp) { + $scope.lakalapayindustry = resp.data; + }) + }; + $scope.loadLakalaPayindustry(); + + $scope.loadLakalaPaySettle = function () { + $http.get('/static/data/lakalapaysettle.json').then(function (resp) { + $scope.lakalapaysettle = resp.data; + }) + }; + $scope.loadLakalaPaySettle(); + + $scope.loadLakalaPayGoods = function () { + $http.get('/static/data/lakalapaygoods.json').then(function (resp) { + $scope.lakalapaygoods = resp.data; + }) + }; + $scope.loadLakalaPayGoods(); + + $scope.loadRoyalpayindustry = function () { + $http.get('/static/data/royalpayindustry.json').then(function (resp) { + $scope.royalpayindustry = resp.data; + }) + }; + $scope.loadRoyalpayindustry(); + + $scope.loadHfindustry = function () { + $http.get('/static/data/hfindustry.json').then(function (resp) { + $scope.hfindustry = resp.data; + }) + }; + $scope.loadHfindustry(); + + $scope.onAlipayMccSelect = function (selectedItem) { + $scope.partner.alipay_category = selectedItem.label; + $scope.partner.alipayindustry = selectedItem.mccCode; + }; + + $scope.onRoyalPayIndustrySelect = function (selectedItem) { + $scope.partner.royalpay_label = selectedItem.label; + $scope.partner.royalpayindustry = selectedItem.mccCode; + }; + + $scope.onHfIndustrySelect = function (selectedItem) { + $scope.partner.hf_label = selectedItem.label; + $scope.partner.hfindustry = selectedItem.mccCode; + }; + + // $scope.t2city_map = angular.copy(t2city_map); + + $scope.timezones = timezone.configs(); + $scope.checkMerchantCodeIsValid = function (code) { + if (code.length != 4) { + $scope.merchantCodeChecked = false; + $scope.merchantIsValid = false; + return; + } + $http.get('/sys/partners/init/check_code_isvalid', {params: {clientMoniker: code}}).then(function (response) { + $scope.merchantIsValid = response.data; + $scope.merchantCodeChecked = true; + }); + }; + $scope.save = function (form) { + if (form.$invalid) { + angular.forEach(form, function (item, key) { + if (key.indexOf('$') < 0) { + item.$dirty = true; + } + }); + return; + } + + if ($scope.partner.company_name.indexOf("Migration") != -1) { + alert("Company Name包含敏感词汇,请检查后重新提交!"); + return; + } + if ($scope.partner.company_phone_a && ('' + $scope.partner.company_phone_a != '')) { + if ($scope.partner.company_phone_a.indexOf('0') == 0) { + alert("Please remove the first character '0' of area code"); + return; + } + } + if ($scope.partner.contact_phone && ('' + $scope.partner.contact_phone != '')) { + if ($scope.partner.contact_phone.indexOf('0') == 0) { + alert("Please remove the first character '0' of area code"); + return; + } + } + $scope.partner.company_phone = '+' + $scope.partner.company_phone_c + ($scope.partner.company_phone_a || '') + $scope.partner.company_phone_p; + $scope.partner.contact_phone = '+' + $scope.partner.contact_phone_c + ($scope.partner.contact_phone_a || '') + $scope.partner.contact_phone_p; + $scope.partner.legal_representative_phone = '+' + $scope.partner.legal_representative_phone_c + ( $scope.partner.legal_representative_phone_a || '') + $scope.partner.legal_representative_phone_p; + $scope.partner.marketing_phone = '+' + $scope.partner.marketing_phone_c + ( $scope.partner.marketing_phone_a || '') + $scope.partner.marketing_phone_p; + if ($scope.partner.company_phone.indexOf(' ') != -1) { + alert('Company Phone can not contain space character'); + return; + } + if ($scope.partner.contact_phone.indexOf(' ') != -1) { + alert('Contact Phone can not contain space character'); + return; + } + if ($scope.partner.legal_representative_phone.indexOf(' ') != -1) { + alert('Representative phone can not contain space character'); + return; + } + if ($scope.partner.marketing_phone.indexOf(' ') != -1) { + alert('Marketing phone can not contain space character'); + return; + } + if ($scope.partner.contact_email.indexOf(' ') != -1) { + alert('Contact email Phone can not contain space character'); + return; + } + if ($scope.partner.legal_representative_email.indexOf(' ') != -1) { + alert('Representative email Phone can not contain space character'); + return; + } + + if ($scope.partner.marketing_email && $scope.partner.marketing_email.indexOf(' ') != -1) { + alert('Marketing email Phone can not contain space character'); + return; + } + if ($scope.partner.suburb.indexOf(' ') != -1) { + alert('suburb can not contain two and more continuous space characters'); + return; + } + if ($scope.partner.registered_suburb.indexOf(' ') != -1) { + alert('Registered suburb can not contain two and more continuous space characters'); + return; + } + if ($scope.partner.acn && $scope.partner.business_structure == 'Company') { + if ($scope.partner.acn.length != 9) { + alert('Acn is not valid'); + return; + } + } + if (!$scope.partner.logo_url) { + alert("Logo is necessary!"); + return; + } + if ($scope.partner.client_pay_type.indexOf('2') >= 0) { + if (!$scope.partner.company_photo) { + alert('Shop Photo1 is necessary'); + return; + } + if (!$scope.partner.store_photo) { + alert('Shop Photo2 is necessary'); + return; + } + } + + if ($scope.partner.referrer_id) { + $scope.referrers.forEach(function (e) { + if ($scope.partner.referrer_id == e.org_id) { + $scope.partner.referrer_name = e.name; + return; + } + }) + } + + if ($scope.partner.client_pay_type.length == 0) { + alert('请选择商户支付场景') + return; + } + if ($scope.partner.client_pay_desc.length == 0) { + alert('请选择商户支付方式') + return; + } + if (typeof ($scope.partner.client_pay_type) == 'string' || typeof ($scope.partner.client_pay_desc) == 'string') { + $scope.partner.client_pay_type = $scope.partner.client_pay_type.split(","); + $scope.partner.client_pay_desc = $scope.partner.client_pay_desc.split(","); + + } + if ($scope.partner.client_pay_type.indexOf('1') >= 0) { + if ($scope.partner.client_pay_desc.join(',').indexOf('10') < 0) { + alert("请检查线上支付场景是否已选择支付方式"); + return; + } + } + if ($scope.partner.client_pay_type.indexOf('2') >= 0) { + if ($scope.partner.client_pay_desc.join(',').indexOf('20') < 0) { + alert("请检查线下支付场景是否已选择支付方式"); + return; + } + } + if ($scope.partner.client_pay_desc.join(',').indexOf('203') >= 0) { + if ($scope.partner.client_pay_desc.join(',').indexOf('2030') < 0 && $scope.partner.client_pay_desc.join(',').indexOf('20399') < 0) { + alert("请检查线下支付是否已选择收银系统类型"); + return; + } + } + $scope.partner.client_pay_type = $scope.partner.client_pay_type.join(','); + $scope.partner.client_pay_desc = $scope.partner.client_pay_desc.join(','); + $http.post('/sys/partners', $scope.partner).then(function (resp) { + commonDialog.alert({title: 'Success', content: 'Register new partner successfully', type: 'success'}); + $scope.updateMerchantLocation(); + // $scope.loadPartners(); + $state.go('partners.detail', {clientMoniker: resp.data.client_moniker}) + }, function (resp) { + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); + }); + }; + $scope.uploadLogo = function (file) { + if (file != null) { + if (file.size > 1 * 1024 * 1024) { + commonDialog.alert({title: 'Error', content: '文件大小不能超过1MB,请压缩后重试', type: 'error'}) + } else { + $scope.logoProgress = {value: 0}; + Upload.upload({ + url: '/attachment/files', + data: {file: file} + }).then(function (resp) { + delete $scope.logoProgress; + $scope.partner.logo_id = resp.data.fileid; + $scope.partner.logo_url = resp.data.url; + }, function (resp) { + delete $scope.logoProgress; + commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) + }, function (evt) { + $scope.logoProgress.value = parseInt(100 * evt.loaded / evt.total); + }) + } + } + }; + + $scope.uploadShopPhoto = function (file) { + if (file != null) { + if (file.size > 2 * 1024 * 1024) { + commonDialog.alert({title: 'Error', content: '文件大小不能超过2MB,请压缩后重试', type: 'error'}) + } else { + $scope.shopPhotoProgress = {value: 0}; + Upload.upload({ + url: '/attachment/files', + data: {file: file} + }).then(function (resp) { + delete $scope.shopPhotoProgress; + $scope.partner.company_photo = resp.data.url; + }, function (resp) { + delete $scope.shopPhotoProgress; + commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) + }, function (evt) { + $scope.shopPhotoProgress.value = parseInt(100 * evt.loaded / evt.total); + }) + } + } + }; + + $scope.uploadStorePhoto = function (file) { + if (file != null) { + if (file.size > 2 * 1024 * 1024) { + commonDialog.alert({title: 'Error', content: '文件大小不能超过2MB,请压缩后重试', type: 'error'}) + } else { + $scope.storePhotoProgress = {value: 0}; + Upload.upload({ + url: '/attachment/files', + data: {file: file} + }).then(function (resp) { + delete $scope.storePhotoProgress; + $scope.partner.store_photo = resp.data.url; + }, function (resp) { + delete $scope.storePhotoProgress; + commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) + }, function (evt) { + $scope.storePhotoProgress.value = parseInt(100 * evt.loaded / evt.total); + }) + } + } + }; + + $scope.updateMerchantLocation = function () { + var params = window.frames['merchant_detail'].merchant_location; + if (params) { + $http.put('/sys/partners/modify/' + $scope.partner.client_moniker + '/location', params).then(function () { + }); + } + } + }]); + app.controller('partnerEditCtrl', ['$scope', '$http', '$state', 'Upload', 'commonDialog', 'timezone', 'partner','upayIndustryMap', + function ($scope, $http, $state, Upload, commonDialog, timezone, partner,upayIndustryMap) { + $scope.upayIndustrys = upayIndustryMap.configs(); + $scope.timezones = timezone.configs(); + $scope.partner = partner.data; + if (!$scope.partner.client_type) { + $scope.partner.client_type = 'cross-border'; + } + if($scope.partner.representativeInfo != null) + { + $scope.partner.registered_address = $scope.partner.representativeInfo.address; + $scope.partner.registered_suburb = $scope.partner.representativeInfo.suburb; + $scope.partner.registered_postcode = $scope.partner.representativeInfo.postcode; + $scope.partner.registered_state = $scope.partner.representativeInfo.state; + $scope.partner.legal_representative_person = $scope.partner.representativeInfo.representative_person; + $scope.partner.legal_representative_phone = $scope.partner.representativeInfo.phone; + $scope.partner.legal_representative_email = $scope.partner.representativeInfo.email; + $scope.partner.legal_representative_job = $scope.partner.representativeInfo.job_title; + + $scope.partner.marketing_person = $scope.partner.representativeInfo.marketing_person; + $scope.partner.marketing_phone = $scope.partner.representativeInfo.marketing_phone; + $scope.partner.marketing_email = $scope.partner.representativeInfo.marketing_email; + $scope.partner.marketing_job = $scope.partner.representativeInfo.marketing_job_title; + + $scope.partner.legal_representative_wechatid = $scope.partner.representativeInfo.legal_representative_wechatid; + $scope.partner.marketing_wechatid = $scope.partner.representativeInfo.marketing_wechatid; + } + + function hasRole() { + var rolenum; + switch (sessionStorage.getItem('role')) { + case "administrator": + rolenum = 1; + break; + case "bduser": + rolenum = 4; + break; + case "salesmanager": + rolenum = 8192; + break; + case "accountant": + rolenum = 8; + break; + case "sitemanager": + rolenum = 128; + break; + case "director": + rolenum = 64; + break; + case "developer": + rolenum = 256; + break; + case "compliance": + rolenum = 2; + break; + case "guest": + rolenum = 2048; + break; + case "orgmanager": + rolenum = 4096; + break; + case "riskmanager": + rolenum = 1024; + break; + default: + break; + } + if ((window.currentUser.role & rolenum) >0) { + return true; + }else { + sessionStorage.removeItem('role'); + return false; + } + } + + if (hasRole()) { + $scope.role = sessionStorage.getItem('role'); + } + + var origin_referrer_id = angular.copy($scope.partner.referrer_id); + var resetClientPayDescByTpey = function (type) { + type = parseInt(type); + if (type == 1) { + removeClientPayDesc($scope.partner.client_pay_desc, '10'); + } + if (type == 2) { + removeClientPayDesc($scope.partner.client_pay_desc, '20'); + } + }; + var compare = function (x, y) { + x = parseInt(x); + y = parseInt(y); + if (x < y) { + return -1; + } else if (x > y) { + return 1; + } else { + return 0; + } + } + $scope.toggleClientPayType = function (type) { + if (!$scope.partner.client_pay_type) { + $scope.partner.client_pay_type = []; + } + var $idx = $scope.partner.client_pay_type.indexOf(type); + if ($idx >= 0) { + $scope.partner.client_pay_type.splice($idx, 1); + resetClientPayDescByTpey(type); + } else { + $scope.partner.client_pay_type.push(type); + $scope.partner.client_pay_type.sort(compare); + } + }; + $scope.toggleClientPayDesc = function (type) { + if (!$scope.partner.client_pay_desc) { + $scope.partner.client_pay_desc = []; + } + var $idx = $scope.partner.client_pay_desc.indexOf(type); + if ($idx >= 0) { + if (type == '203') { + removeClientPayDesc($scope.partner.client_pay_desc, '2030') + } + $scope.partner.client_pay_desc.splice($idx, 1); + } else { + $scope.partner.client_pay_desc.push(type); + $scope.partner.client_pay_desc.sort(compare); + } + }; + + $scope.partner.sameAsContactPerson = false; + $scope.checkboxOnclick = function (){ + $scope.partner.sameAsContactPerson = !($scope.partner.sameAsContactPerson); + if($scope.partner.sameAsContactPerson) { + $scope.partner.legal_representative_person = $scope.partner.contact_person; + $scope.partner.legal_representative_phone = $scope.partner.contact_phone; + $scope.partner.legal_representative_email = $scope.partner.contact_email; + $scope.partner.legal_representative_job = $scope.partner.contact_job; + $scope.partner.legal_representative_wechatid = $scope.partner.contact_wechatid; + } + } + + $scope.partner.marketingSameAsContact = false; + $scope.checkMarketingSameAsContact = function (){ + $scope.partner.marketingSameAsContact = !($scope.partner.marketingSameAsContact); + if($scope.partner.marketingSameAsContact) { + $scope.partner.marketing_person = $scope.partner.contact_person; + $scope.partner.marketing_phone = $scope.partner.contact_phone; + $scope.partner.marketing_email = $scope.partner.contact_email; + $scope.partner.marketing_job = $scope.partner.contact_job; + $scope.partner.marketing_wechatid = $scope.partner.contact_wechatid; + } + } + + $scope.partner.sameAsAddress=false; + $scope.sameAddress = function (){ + $scope.partner.sameAsAddress=!($scope.partner.sameAsAddress); + if($scope.partner.sameAsAddress) { + $scope.partner.registered_address = $scope.partner.address; + $scope.partner.registered_suburb = $scope.partner.suburb; + $scope.partner.registered_postcode = $scope.partner.postcode; + $scope.partner.registered_state = $scope.partner.state; + } + } + + $scope.listReferrers = function () { + $http.get('/sys/orgs/referrer').then(function (resp) { + $scope.referrers = resp.data; + }) + }; + $scope.listReferrers(); + + $scope.loadAlipayCategory = function () { + $http.get('/static/data/alipayMcc.json').then(function (resp) { + $scope.alipayMccCategory = resp.data; + }) + }; + $scope.loadAlipayCategory(); + $scope.loadJDindustry = function () { + $http.get('/static/data/jdindustry.json').then(function (resp) { + $scope.jdindustry = resp.data; + }) + }; + $scope.loadJDindustry(); + + $scope.loadLakalaPayindustry = function () { + $http.get('/static/data/lakalapayindustry.json').then(function (resp) { + $scope.lakalapayindustry = resp.data; + }) + }; + $scope.loadLakalaPayindustry(); + + $scope.loadLakalaPaySettle = function () { + $http.get('/static/data/lakalapaysettle.json').then(function (resp) { + $scope.lakalapaysettle = resp.data; + }) + }; + $scope.loadLakalaPaySettle(); + + $scope.loadLakalaPayGoods = function () { + $http.get('/static/data/lakalapaygoods.json').then(function (resp) { + $scope.lakalapaygoods = resp.data; + }) + }; + $scope.loadLakalaPayGoods(); + + $scope.loadRoyalpayindustry = function () { + $http.get('/static/data/royalpayindustry.json').then(function (resp) { + $scope.royalpayindustry = resp.data; + }) + }; + $scope.loadRoyalpayindustry(); + + $scope.loadHfindustry = function () { + $http.get('/static/data/hfindustry.json').then(function (resp) { + $scope.hfindustry = resp.data; + }) + }; + $scope.loadHfindustry(); + + $scope.onAlipayMccSelect = function (selectedItem) { + $scope.partner.alipay_category = selectedItem.label; + $scope.partner.alipayindustry = selectedItem.mccCode; + }; + $scope.onRoyalPayIndustrySelect = function (selectedItem) { + $scope.partner.royalpay_label = selectedItem.label; + $scope.partner.royalpayindustry = selectedItem.mccCode; + }; + $scope.onHfIndustrySelect = function (selectedItem) { + $scope.partner.hf_label = selectedItem.label; + $scope.partner.hfindustry = selectedItem.mccCode; + }; + + + $scope.updatePartner = function (form) { + if (form.$invalid) { + angular.forEach(form, function (item, key) { + if (key.indexOf('$') < 0) { + item.$dirty = true; + } + }); + return; + } + + if ($scope.partner.company_name.indexOf("Migration") != -1) { + alert("Company Name包含敏感词汇,请检查后重新提交!"); + return; + } + if ($scope.partner.company_phone.indexOf(' ') != -1) { + alert('Company Phone can not contain space character'); + return; + } + if ($scope.partner.contact_email.indexOf(' ') != -1) { + alert('Contact email Phone can not contain space character'); + return; + } + if ($scope.partner.suburb.indexOf(' ') != -1) { + alert('suburb can not contain two and more continuous space characters'); + return; + } + if ($scope.partner.client_pay_type.indexOf('2') >= 0) { + if (!$scope.partner.company_photo) { + alert('Shop Photo1 is necessary'); + return; + } + if (!$scope.partner.store_photo) { + alert('Shop Photo2 is necessary'); + return; + } + } + + if ($scope.partner.acn && $scope.partner.business_structure == 'Company') { + if ($scope.partner.acn.length != 9) { + alert('Acn is not valid'); + } + } + if ($scope.partner.referrer_id) { + $scope.referrers.forEach(function (e) { + if ($scope.partner.referrer_id == e.org_id) { + $scope.partner.referrer_name = e.name; + return; + } + }) + } + var content = ''; + if (!origin_referrer_id && $scope.partner.referrer_id) { + content = 'Update partner info successfully,But You Had add new Referrer,Please Change the BD Commission Proportion!'; + } + if ($scope.partner.client_pay_type.length == 0) { + alert('请选择商户支付场景') + return; + } + if ($scope.partner.client_pay_desc.length == 0) { + alert('请选择商户支付方式') + return; + } + if ($scope.partner.client_pay_type.indexOf('1') >= 0) { + if ($scope.partner.client_pay_desc.join(',').indexOf('10') < 0) { + alert("请检查线上支付场景是否已选择支付方式"); + return; + } + } + if ($scope.partner.client_pay_type.indexOf('2') >= 0) { + if ($scope.partner.client_pay_desc.join(',').indexOf('20') < 0) { + alert("请检查线下支付场景是否已选择支付方式"); + return; + } + } + if ($scope.partner.client_pay_desc.join(',').indexOf('203') >= 0) { + if ($scope.partner.client_pay_desc.join(',').indexOf('2030') < 0 && $scope.partner.client_pay_desc.join(',').indexOf('20399') < 0) { + alert("请检查线下支付是否已选择收银系统类型"); + return; + } + } + $scope.partner.client_pay_type = $scope.partner.client_pay_type.join(','); + $scope.partner.client_pay_desc = $scope.partner.client_pay_desc.join(','); + $http.put('/sys/partners/' + $scope.partner.client_moniker, $scope.partner).then(function () { + if (content != '') { + commonDialog.alert({ + title: 'Warning', + content: content, + type: 'error' + }); + } else { + commonDialog.alert({ + title: 'Success', + content: 'Update partner information successfully', + type: 'success' + }); + } + $scope.updateMerchantLocation(); + $scope.loadPartners(); + $state.go('^.detail', {clientMoniker: $scope.partner.client_moniker}, {reload: true}); + }, function (resp) { + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}) + }); + }; + $scope.uploadLogo = function (file) { + if (file != null) { + if (file.size > 1 * 1024 * 1024) { + commonDialog.alert({title: 'Error', content: '文件大小不能超过1MB,请压缩后重试', type: 'error'}) + } else { + $scope.logoProgress = {value: 0}; + Upload.upload({ + url: '/attachment/files', + data: {file: file} + }).then(function (resp) { + delete $scope.logoProgress; + $scope.partner.logo_id = resp.data.fileid; + $scope.partner.logo_url = resp.data.url; + }, function (resp) { + delete $scope.logoProgress; + commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) + }, function (evt) { + $scope.logoProgress.value = parseInt(100 * evt.loaded / evt.total); + }) + } + } + }; + + $scope.uploadShopPhoto = function (file) { + if (file != null) { + if (file.size > 2 * 1024 * 1024) { + commonDialog.alert({title: 'Error', content: '文件大小不能超过2MB,请压缩后重试', type: 'error'}) + } else { + $scope.shopPhotoProgress = {value: 0}; + Upload.upload({ + url: '/attachment/files', + data: {file: file} + }).then(function (resp) { + delete $scope.shopPhotoProgress; + $scope.partner.company_photo = resp.data.url; + }, function (resp) { + delete $scope.shopPhotoProgress; + commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) + }, function (evt) { + $scope.shopPhotoProgress.value = parseInt(100 * evt.loaded / evt.total); + }) + } + } + }; + + $scope.uploadStorePhoto = function (file) { + if (file != null) { + if (file.size > 2 * 1024 * 1024) { + commonDialog.alert({title: 'Error', content: '文件大小不能超过2MB,请压缩后重试', type: 'error'}) + } else { + $scope.storePhotoProgress = {value: 0}; + Upload.upload({ + url: '/attachment/files', + data: {file: file} + }).then(function (resp) { + delete $scope.storePhotoProgress; + $scope.partner.store_photo = resp.data.url; + }, function (resp) { + delete $scope.storePhotoProgress; + commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) + }, function (evt) { + $scope.storePhotoProgress.value = parseInt(100 * evt.loaded / evt.total); + }) + } + } + }; + + $scope.getMerchantLocation = function () { + $http.get('/sys/partners/' + $scope.partner.client_moniker + '/location').then(function (resp) { + $scope.merchant_location = resp.data; + }); + }; + $scope.getMerchantLocation(); + + $scope.updateMerchantLocation = function () { + var params = window.frames['merchant_detail'].merchant_location; + if (params) { + $http.put('/sys/partners/modify/' + $scope.partner.client_moniker + '/location', params).then(function () { + }); + } + } + }]); + return app; +}); diff --git a/src/main/ui/static/payment/partner/partner-manage.js b/src/main/ui/static/payment/partner/partner-manage.js index 558192fb3..6f74bc965 100644 --- a/src/main/ui/static/payment/partner/partner-manage.js +++ b/src/main/ui/static/payment/partner/partner-manage.js @@ -96,10 +96,6 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter templateUrl: '/static/payment/partner/templates/partners.html', controller: 'partnerListCtrl', data: {label: '商户列表'} - }).state('newPartners', { - url: '/partners/new', - templateUrl: '/static/payment/partner/templates/add_partner.html', - controller: 'addPartnerCtrl' }).state('businessCompliance', { url: '/partners/compliance', templateUrl: '/static/payment/partner/templates/partner_compliance.html', @@ -117,15 +113,6 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter return $http.get('/sys/partners/' + $stateParams.clientMoniker); }] } - }).state('partners.edit', { - url: '/{clientMoniker}/edit', - templateUrl: '/static/payment/partner/templates/partner_edit.html', - controller: 'partnerEditCtrl', - resolve: { - partner: ['$http', '$stateParams', function ($http, $stateParams) { - return $http.get('/sys/partners/' + $stateParams.clientMoniker); - }] - } }).state('partners.detail.payment_info', { url: '/payment', templateUrl: '/static/payment/partner/templates/partner_payment_info.html', @@ -161,13 +148,17 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter }).state('partners.detail.files', { url: '/files', templateUrl: '/static/payment/partner/templates/partner_auth_files.html', - controller: 'partnerAuthFileCtrl', + controller: 'partnerAuthFileCtrl' + }).state('partners.detail.files.CP_files', { + url: '/cp_files', + templateUrl: '/static/payment/partner/templates/partner_cp_auth_files.html', + controller: 'partnerCPAuthFileCtrl', resolve: { file: ['$http', '$stateParams', function ($http, $stateParams) { return $http.get('/sys/partners/' + $stateParams.clientMoniker + '/file'); }] } - }).state('partners.detail.MW_files', { + }).state('partners.detail.files.MW_files', { url: '/mw_files', templateUrl: '/static/payment/partner/templates/partner_mw_auth_files.html', controller: 'partnerMWAuthFileCtrl', @@ -427,436 +418,6 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter }; }]); - app.controller('addPartnerCtrl', ['$rootScope', '$scope', '$http', '$state', 'Upload', 'commonDialog', 'timezone', 'businessStructuresMap', 'industryMap', 'stateMap', 'sectorMap', 'countryMap', function ($rootScope, $scope, $http, $state, Upload, commonDialog, timezone, businessStructuresMap, industryMap, stateMap, sectorMap, countryMap) { - if ($scope.partner_application) { - $scope.partner = angular.copy($scope.partner_application); - delete $rootScope.partner_application; - } else { - $scope.partner = {timezone: 'Australia/Melbourne'}; - } - $scope.initMerchantCode = function () { - $http.get('/sys/partners/init/merchant_code').then(function (response) { - $scope.partner.client_moniker = response.data.partner_code; - $scope.merchantCodeChecked = true; - $scope.merchantIsValid = true; - }); - }; - $scope.initMerchantCode(); - $scope.partner.company_phone_c = 61; - $scope.partner.contact_phone_c = 61; - $scope.partner.client_pay_type = []; - $scope.partner.client_pay_desc = []; - var resetClientPayDescByTpey = function (type) { - type = parseInt(type); - if (type == 1) { - removeClientPayDesc($scope.partner.client_pay_desc, '10'); - } - if (type == 2) { - removeClientPayDesc($scope.partner.client_pay_desc, '20'); - } - }; - $scope.partner.sameAsContactPerson = false; - $scope.checkboxOnclick = function (){ - $scope.partner.sameAsContactPerson = !($scope.partner.sameAsContactPerson); - if($scope.partner.sameAsContactPerson) { - $scope.partner.legal_representative_person = $scope.partner.contact_person; - $scope.partner.legal_representative_phone_a = $scope.partner.contact_phone_a; - $scope.partner.legal_representative_phone_c = $scope.partner.contact_phone_c; - $scope.partner.legal_representative_phone_p = $scope.partner.contact_phone_p; - $scope.partner.legal_representative_email = $scope.partner.contact_email; - $scope.partner.legal_representative_job = $scope.partner.contact_job; - $scope.partner.legal_representative_wechatid = $scope.partner.contact_wechatid; - } - } - - $scope.partner.marketingSameAsContact = false; - $scope.checkMarketingSameAsContact = function (){ - $scope.partner.marketingSameAsContact = !($scope.partner.marketingSameAsContact); - if($scope.partner.marketingSameAsContact) { - $scope.partner.marketing_person = $scope.partner.contact_person; - $scope.partner.marketing_phone_a = $scope.partner.contact_phone_a; - $scope.partner.marketing_phone_c = $scope.partner.contact_phone_c; - $scope.partner.marketing_phone_p = $scope.partner.contact_phone_p; - $scope.partner.marketing_email = $scope.partner.contact_email; - $scope.partner.marketing_job = $scope.partner.contact_job; - $scope.partner.marketing_wechatid = $scope.partner.contact_wechatid; - } - } - - $scope.partner.sameAsAddress=false; - $scope.sameAddress = function (){ - $scope.partner.sameAsAddress = !($scope.partner.sameAsAddress); - if($scope.partner.sameAsAddress) { - $scope.partner.registered_address = $scope.partner.address; - $scope.partner.registered_suburb = $scope.partner.suburb; - $scope.partner.registered_postcode = $scope.partner.postcode; - $scope.partner.registered_state = $scope.partner.state; - } - } - - var compare = function (x, y) { - x = parseInt(x); - y = parseInt(y); - if (x < y) { - return -1; - } else if (x > y) { - return 1; - } else { - return 0; - } - } - $scope.toggleClientPayType = function (type) { - if ($scope.partner.client_pay_type == null || $scope.partner.client_pay_type == undefined) { - $scope.partner.client_pay_type = []; - } - var $idx = $scope.partner.client_pay_type.indexOf(type); - if ($idx >= 0) { - $scope.partner.client_pay_type.splice($idx, 1); - resetClientPayDescByTpey(type); - } else { - $scope.partner.client_pay_type.push(type); - $scope.partner.client_pay_type.sort(compare); - } - }; - $scope.toggleClientPayDesc = function (type) { - if ($scope.partner.client_pay_desc == null || $scope.partner.client_pay_desc == undefined) { - $scope.partner.client_pay_desc = []; - } - var $idx = $scope.partner.client_pay_desc.indexOf(type); - if ($idx >= 0) { - if (type == '203') { - removeClientPayDesc($scope.partner.client_pay_desc, '2030') - } - $scope.partner.client_pay_desc.splice($idx, 1); - } else { - $scope.partner.client_pay_desc.push(type); - $scope.partner.client_pay_desc.sort(compare); - } - }; - $scope.pagination = {}; - $scope.industries = industryMap.configs(); - $scope.states = stateMap.configs(); - $scope.countries = countryMap.configs(); - $scope.sectors = sectorMap.configs(); - $scope.business_structures = businessStructuresMap.configs(); - $scope.clean_days = angular.copy(clean_days_map); - $scope.bd_citys = angular.copy(bd_city_map); - $scope.params = {textType: 'all', org_name: 'ALL'}; - $scope.merchantIsValid = false; - $scope.merchantCodeChecked = false; - - function remove(arr, val) { - if (angular.isArray(arr)) { - for (var i = arr.length; i--;) { - if (arr[i].value == val) { - arr.splice(i, 1); - break; - } - } - } - return arr; - } - - var industries = angular.copy($scope.industries); - $scope.industries = remove(industries, 331); - - $scope.listReferrers = function () { - $http.get('/sys/orgs/referrer').then(function (resp) { - $scope.referrers = resp.data; - }) - }; - $scope.listReferrers(); - - $scope.loadAlipayCategory = function () { - $http.get('/static/data/alipayMcc.json').then(function (resp) { - $scope.alipayMccCategory = resp.data; - }) - }; - $scope.loadAlipayCategory(); - $scope.loadJDindustry = function () { - $http.get('/static/data/jdindustry.json').then(function (resp) { - $scope.jdindustry = resp.data; - }) - }; - $scope.loadJDindustry(); - - $scope.loadLakalaPayindustry = function () { - $http.get('/static/data/lakalapayindustry.json').then(function (resp) { - $scope.lakalapayindustry = resp.data; - }) - }; - $scope.loadLakalaPayindustry(); - - $scope.loadLakalaPaySettle = function () { - $http.get('/static/data/lakalapaysettle.json').then(function (resp) { - $scope.lakalapaysettle = resp.data; - }) - }; - $scope.loadLakalaPaySettle(); - - $scope.loadLakalaPayGoods = function () { - $http.get('/static/data/lakalapaygoods.json').then(function (resp) { - $scope.lakalapaygoods = resp.data; - }) - }; - $scope.loadLakalaPayGoods(); - - $scope.loadRoyalpayindustry = function () { - $http.get('/static/data/royalpayindustry.json').then(function (resp) { - $scope.royalpayindustry = resp.data; - }) - }; - $scope.loadRoyalpayindustry(); - - $scope.loadHfindustry = function () { - $http.get('/static/data/hfindustry.json').then(function (resp) { - $scope.hfindustry = resp.data; - }) - }; - $scope.loadHfindustry(); - - $scope.onAlipayMccSelect = function (selectedItem) { - $scope.partner.alipay_category = selectedItem.label; - $scope.partner.alipayindustry = selectedItem.mccCode; - }; - - $scope.onRoyalPayIndustrySelect = function (selectedItem) { - $scope.partner.royalpay_label = selectedItem.label; - $scope.partner.royalpayindustry = selectedItem.mccCode; - }; - - $scope.onHfIndustrySelect = function (selectedItem) { - $scope.partner.hf_label = selectedItem.label; - $scope.partner.hfindustry = selectedItem.mccCode; - }; - - // $scope.t2city_map = angular.copy(t2city_map); - - $scope.timezones = timezone.configs(); - $scope.checkMerchantCodeIsValid = function (code) { - if (code.length != 4) { - $scope.merchantCodeChecked = false; - $scope.merchantIsValid = false; - return; - } - $http.get('/sys/partners/init/check_code_isvalid', {params: {clientMoniker: code}}).then(function (response) { - $scope.merchantIsValid = response.data; - $scope.merchantCodeChecked = true; - }); - }; - $scope.save = function (form) { - if (form.$invalid) { - angular.forEach(form, function (item, key) { - if (key.indexOf('$') < 0) { - item.$dirty = true; - } - }); - return; - } - - if ($scope.partner.company_name.indexOf("Migration") != -1) { - alert("Company Name包含敏感词汇,请检查后重新提交!"); - return; - } - if ($scope.partner.company_phone_a && ('' + $scope.partner.company_phone_a != '')) { - if ($scope.partner.company_phone_a.indexOf('0') == 0) { - alert("Please remove the first character '0' of area code"); - return; - } - } - if ($scope.partner.contact_phone && ('' + $scope.partner.contact_phone != '')) { - if ($scope.partner.contact_phone.indexOf('0') == 0) { - alert("Please remove the first character '0' of area code"); - return; - } - } - $scope.partner.company_phone = '+' + $scope.partner.company_phone_c + ($scope.partner.company_phone_a || '') + $scope.partner.company_phone_p; - $scope.partner.contact_phone = '+' + $scope.partner.contact_phone_c + ($scope.partner.contact_phone_a || '') + $scope.partner.contact_phone_p; - $scope.partner.legal_representative_phone = '+' + $scope.partner.legal_representative_phone_c + ( $scope.partner.legal_representative_phone_a || '') + $scope.partner.legal_representative_phone_p; - $scope.partner.marketing_phone = '+' + $scope.partner.marketing_phone_c + ( $scope.partner.marketing_phone_a || '') + $scope.partner.marketing_phone_p; - if ($scope.partner.company_phone.indexOf(' ') != -1) { - alert('Company Phone can not contain space character'); - return; - } - if ($scope.partner.contact_phone.indexOf(' ') != -1) { - alert('Contact Phone can not contain space character'); - return; - } - if ($scope.partner.legal_representative_phone.indexOf(' ') != -1) { - alert('Representative phone can not contain space character'); - return; - } - if ($scope.partner.marketing_phone.indexOf(' ') != -1) { - alert('Marketing phone can not contain space character'); - return; - } - if ($scope.partner.contact_email.indexOf(' ') != -1) { - alert('Contact email Phone can not contain space character'); - return; - } - if ($scope.partner.legal_representative_email.indexOf(' ') != -1) { - alert('Representative email Phone can not contain space character'); - return; - } - if ($scope.partner.marketing_email.indexOf(' ') != -1) { - alert('Marketing email Phone can not contain space character'); - return; - } - if ($scope.partner.suburb.indexOf(' ') != -1) { - alert('suburb can not contain two and more continuous space characters'); - return; - } - if ($scope.partner.registered_suburb.indexOf(' ') != -1) { - alert('Registered suburb can not contain two and more continuous space characters'); - return; - } - if ($scope.partner.acn && $scope.partner.business_structure == 'Company') { - if ($scope.partner.acn.length != 9) { - alert('Acn is not valid'); - return; - } - } - if (!$scope.partner.logo_url) { - alert("Logo is necessary!"); - return; - } - if ($scope.partner.client_pay_type.indexOf('2') >= 0) { - if (!$scope.partner.company_photo) { - alert('Shop Photo1 is necessary'); - return; - } - if (!$scope.partner.store_photo) { - alert('Shop Photo2 is necessary'); - return; - } - } - - if ($scope.partner.referrer_id) { - $scope.referrers.forEach(function (e) { - if ($scope.partner.referrer_id == e.org_id) { - $scope.partner.referrer_name = e.name; - return; - } - }) - } - - if ($scope.partner.client_pay_type.length == 0) { - alert('请选择商户支付场景') - return; - } - if ($scope.partner.client_pay_desc.length == 0) { - alert('请选择商户支付方式') - return; - } - if (typeof ($scope.partner.client_pay_type) == 'string' || typeof ($scope.partner.client_pay_desc) == 'string') { - $scope.partner.client_pay_type = $scope.partner.client_pay_type.split(","); - $scope.partner.client_pay_desc = $scope.partner.client_pay_desc.split(","); - - } - if ($scope.partner.client_pay_type.indexOf('1') >= 0) { - if ($scope.partner.client_pay_desc.join(',').indexOf('10') < 0) { - alert("请检查线上支付场景是否已选择支付方式"); - return; - } - } - if ($scope.partner.client_pay_type.indexOf('2') >= 0) { - if ($scope.partner.client_pay_desc.join(',').indexOf('20') < 0) { - alert("请检查线下支付场景是否已选择支付方式"); - return; - } - } - if ($scope.partner.client_pay_desc.join(',').indexOf('203') >= 0) { - if ($scope.partner.client_pay_desc.join(',').indexOf('2030') < 0 && $scope.partner.client_pay_desc.join(',').indexOf('20399') < 0) { - alert("请检查线下支付是否已选择收银系统类型"); - return; - } - } - $scope.partner.client_pay_type = $scope.partner.client_pay_type.join(','); - $scope.partner.client_pay_desc = $scope.partner.client_pay_desc.join(','); - $http.post('/sys/partners', $scope.partner).then(function (resp) { - commonDialog.alert({title: 'Success', content: 'Register new partner successfully', type: 'success'}); - $scope.updateMerchantLocation(); - // $scope.loadPartners(); - $state.go('partners.detail', {clientMoniker: resp.data.client_moniker}) - }, function (resp) { - commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); - }); - }; - $scope.uploadLogo = function (file) { - if (file != null) { - if (file.size > 1 * 1024 * 1024) { - commonDialog.alert({title: 'Error', content: '文件大小不能超过1MB,请压缩后重试', type: 'error'}) - } else { - $scope.logoProgress = {value: 0}; - Upload.upload({ - url: '/attachment/files', - data: {file: file} - }).then(function (resp) { - delete $scope.logoProgress; - $scope.partner.logo_id = resp.data.fileid; - $scope.partner.logo_url = resp.data.url; - }, function (resp) { - delete $scope.logoProgress; - commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) - }, function (evt) { - $scope.logoProgress.value = parseInt(100 * evt.loaded / evt.total); - }) - } - } - }; - - $scope.uploadShopPhoto = function (file) { - if (file != null) { - if (file.size > 2 * 1024 * 1024) { - commonDialog.alert({title: 'Error', content: '文件大小不能超过2MB,请压缩后重试', type: 'error'}) - } else { - $scope.shopPhotoProgress = {value: 0}; - Upload.upload({ - url: '/attachment/files', - data: {file: file} - }).then(function (resp) { - delete $scope.shopPhotoProgress; - $scope.partner.company_photo = resp.data.url; - }, function (resp) { - delete $scope.shopPhotoProgress; - commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) - }, function (evt) { - $scope.shopPhotoProgress.value = parseInt(100 * evt.loaded / evt.total); - }) - } - } - }; - - $scope.uploadStorePhoto = function (file) { - if (file != null) { - if (file.size > 2 * 1024 * 1024) { - commonDialog.alert({title: 'Error', content: '文件大小不能超过2MB,请压缩后重试', type: 'error'}) - } else { - $scope.storePhotoProgress = {value: 0}; - Upload.upload({ - url: '/attachment/files', - data: {file: file} - }).then(function (resp) { - delete $scope.storePhotoProgress; - $scope.partner.store_photo = resp.data.url; - }, function (resp) { - delete $scope.storePhotoProgress; - commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) - }, function (evt) { - $scope.storePhotoProgress.value = parseInt(100 * evt.loaded / evt.total); - }) - } - } - }; - - $scope.updateMerchantLocation = function () { - var params = window.frames['merchant_detail'].merchant_location; - if (params) { - $http.put('/sys/partners/modify/' + $scope.partner.client_moniker + '/location', params).then(function () { - }); - } - } - }]); app.controller('partnerDetailCtrl', ['$scope', '$http', '$state', '$uibModal', '$rootScope', 'Upload', 'commonDialog', 'partner', '$sce', function ($scope, $http, $state, $uibModal, $rootScope, Upload, commonDialog, partner, $sce) { $scope.init = {wechat_compliance: false, local_merchant: false}; $scope.partner = partner.data; @@ -1135,612 +696,198 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); }) } - }) - }; - $scope.apply2makeAgreeFile = function () { - $http.get('/sys/partners/' + $scope.partner.client_moniker + '/make_agree_file').then(function () { - commonDialog.alert({ - title: 'Success!', - content: '已提交制作合同!', - type: 'success' - }); - $state.reload(); - }, function (resp) { - commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); - } - ); - }; - - $scope.commit2GreenChannel = function () { - commonDialog.confirm({ - title: 'Audit Partner', - content: 'Are you sure to mark partner ' + $scope.partner.company_name + ' Green Channel?' - }).then(function () { - $http.put('/sys/partners/' + $scope.partner.client_moniker + '/compliance/green_channel').then(function () { - commonDialog.alert({ - title: 'Success', - content: 'Commit to Green Channel successfully', - type: 'success' - }); - $state.reload(); - }, function (resp) { - commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); - }) - - }) - }; - - $scope.markAuditEmail = function () { - commonDialog.confirm({ - title: 'Warning', - content: 'Make sure you have send the email to client.' - }).then(function () { - $http.put('/sys/partners/' + $scope.partner.client_moniker + '/audit/email_sending_status').then(function () { - $state.reload(); - }, function (resp) { - commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); - }) - }) - }; - $scope.resendApproveEmail = function () { - commonDialog.confirm({ - title: 'Warning', - content: 'This operation will reset the password of admin user. Are you sure this email is correct ? Or you may update this information first.' - }).then(function () { - $http.put('/sys/partners/' + $scope.partner.client_moniker + '/audit/send_email').then(function () { - $state.reload(); - }, function (resp) { - commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); - }) - }) - }; - $scope.editBDUser = function () { - $uibModal.open({ - templateUrl: '/static/payment/partner/templates/bd_user_choose_dialog.html', - controller: 'partnerChooseBDUserDialogCtrl', - resolve: { - bdUsers: ['$http', function ($http) { - return $http.get('/sys/manager_accounts/roles/bd_user'); - }], - partner: function () { - return $scope.partner; - }, - type: function () { - return 'edit'; - } - } - }).result.then(function () { - $state.reload(); - }) - }; - $scope.bindBDUser = function () { - $uibModal.open({ - templateUrl: '/static/payment/partner/templates/bd_user_choose_dialog.html', - controller: 'partnerChooseBDUserDialogCtrl', - resolve: { - bdUsers: ['$http', function ($http) { - return $http.get('/sys/manager_accounts/roles/bd_user'); - }], - partner: function () { - return $scope.partner; - }, - type: function () { - return 'add'; - } - } - }).result.then(function () { - $state.reload(); - }) - }; - - $scope.configMasterMerchant = function () { - commonDialog.inputText({title: 'Input Master Merchant Code'}).then(function (text) { - $http.put('/sys/partners/' + $scope.partner.client_moniker + '/master_configuration', {master_merchant: text}).then(function () { - commonDialog.alert({title: 'Success', content: "Master Merchant Code:" + text, type: 'success'}); - }, function (resp) { - commonDialog.alert({ - title: 'Config Master Merchant Failed', - content: resp.data.message, - type: 'error' - }); - }) - }) - }; - - $scope.getMerchantLocation = function () { - $http.get('/sys/partners/' + $scope.partner.client_moniker + '/location').then(function (resp) { - $scope.merchant_location = resp.data; - }); - }; - $scope.getMerchantLocation(); - - - $scope.complianceCheck = function () { - if (!$rootScope.complianceCheck) { - $rootScope.complianceCheck = {}; - } - $rootScope.complianceCheck.client_id = $scope.partner.client_id; - $rootScope.complianceCheck.clientInfo = true; - }; - $scope.complianceChangeCheck = function () { - if ($rootScope.complianceCheck) { - if ($scope.partner.client_id != $rootScope.complianceCheck.client_id) { - delete $rootScope.complianceCheck; - } - } - }; - $scope.complianceChangeCheck(); - - $scope.changeWechatCompliance = function () { - if (!$scope.partner) { - return; - } - if (!$state.is('partners.detail')) { - $scope.init.wechat_compliance = false; - return; - } - if (!$scope.init.wechat_compliance) { - $scope.init.wechat_compliance = true; - return; - } - $http.put('/sys/partners/' + $scope.partner.client_moniker + '/wechat_compliance_permission', {allow: $scope.partner.wechat_compliance}).then(function () { - - }, function (resp) { - commonDialog.alert({ - title: 'failed to change wechat_compliance permission status', - content: resp.data.message, - type: 'error' - }) - }) - }; - $scope.changeLocalMerchant = function () { - if (!$scope.partner) { - return; - } - if (!$state.is('partners.detail')) { - $scope.init.local_merchant = false; - return; - } - if (!$scope.init.local_merchant) { - $scope.init.local_merchant = true; - return; - } - $http.put('/sys/partners/' + $scope.partner.client_moniker + '/local_merchant_permission', {allow: $scope.partner.local_merchant}).then(function () { - - }, function (resp) { - commonDialog.alert({ - title: 'failed to change local_merchant permission status', - content: resp.data.message, - type: 'error' - }) - }) - }; - - $scope.removeSub = function () { - $http.delete('/sys/partners/unsub/' + $scope.partner.client_moniker).then(function (resp) { - $state.reload(); - }); - }; - $scope.addSub = function () { - $http.put('/sys/partners/unsub/' + $scope.partner.client_moniker).then(function (resp) { - $state.reload(); - }); - }; - }]); - app.controller('partnerEditCtrl', ['$scope', '$http', '$state', 'Upload', 'commonDialog', 'timezone', 'partner', - function ($scope, $http, $state, Upload, commonDialog, timezone, partner) { - $scope.timezones = timezone.configs(); - $scope.partner = partner.data; - if($scope.partner.representativeInfo != null) - { - $scope.partner.registered_address = $scope.partner.representativeInfo.address; - $scope.partner.registered_suburb = $scope.partner.representativeInfo.suburb; - $scope.partner.registered_postcode = $scope.partner.representativeInfo.postcode; - $scope.partner.registered_state = $scope.partner.representativeInfo.state; - $scope.partner.legal_representative_person = $scope.partner.representativeInfo.representative_person; - $scope.partner.legal_representative_phone = $scope.partner.representativeInfo.phone; - $scope.partner.legal_representative_email = $scope.partner.representativeInfo.email; - $scope.partner.legal_representative_job = $scope.partner.representativeInfo.job_title; - - $scope.partner.marketing_person = $scope.partner.representativeInfo.marketing_person; - $scope.partner.marketing_phone = $scope.partner.representativeInfo.marketing_phone; - $scope.partner.marketing_email = $scope.partner.representativeInfo.marketing_email; - $scope.partner.marketing_job = $scope.partner.representativeInfo.marketing_job_title; - - $scope.partner.legal_representative_wechatid = $scope.partner.representativeInfo.legal_representative_wechatid; - $scope.partner.marketing_wechatid = $scope.partner.representativeInfo.marketing_wechatid; - } - - function hasRole() { - var rolenum; - switch (sessionStorage.getItem('role')) { - case "administrator": - rolenum = 1; - break; - case "bduser": - rolenum = 4; - break; - case "salesmanager": - rolenum = 8192; - break; - case "accountant": - rolenum = 8; - break; - case "sitemanager": - rolenum = 128; - break; - case "director": - rolenum = 64; - break; - case "developer": - rolenum = 256; - break; - case "compliance": - rolenum = 2; - break; - case "guest": - rolenum = 2048; - break; - case "orgmanager": - rolenum = 4096; - break; - case "riskmanager": - rolenum = 1024; - break; - default: - break; - } - if ((window.currentUser.role & rolenum) >0) { - return true; - }else { - sessionStorage.removeItem('role'); - return false; - } - } - - if (hasRole()) { - $scope.role = sessionStorage.getItem('role'); - } - - var origin_referrer_id = angular.copy($scope.partner.referrer_id); - var resetClientPayDescByTpey = function (type) { - type = parseInt(type); - if (type == 1) { - removeClientPayDesc($scope.partner.client_pay_desc, '10'); - } - if (type == 2) { - removeClientPayDesc($scope.partner.client_pay_desc, '20'); - } - }; - var compare = function (x, y) { - x = parseInt(x); - y = parseInt(y); - if (x < y) { - return -1; - } else if (x > y) { - return 1; - } else { - return 0; - } - } - $scope.toggleClientPayType = function (type) { - if (!$scope.partner.client_pay_type) { - $scope.partner.client_pay_type = []; - } - var $idx = $scope.partner.client_pay_type.indexOf(type); - if ($idx >= 0) { - $scope.partner.client_pay_type.splice($idx, 1); - resetClientPayDescByTpey(type); - } else { - $scope.partner.client_pay_type.push(type); - $scope.partner.client_pay_type.sort(compare); - } - }; - $scope.toggleClientPayDesc = function (type) { - if (!$scope.partner.client_pay_desc) { - $scope.partner.client_pay_desc = []; - } - var $idx = $scope.partner.client_pay_desc.indexOf(type); - if ($idx >= 0) { - if (type == '203') { - removeClientPayDesc($scope.partner.client_pay_desc, '2030') - } - $scope.partner.client_pay_desc.splice($idx, 1); - } else { - $scope.partner.client_pay_desc.push(type); - $scope.partner.client_pay_desc.sort(compare); - } - }; - - $scope.partner.sameAsContactPerson = false; - $scope.checkboxOnclick = function (){ - $scope.partner.sameAsContactPerson = !($scope.partner.sameAsContactPerson); - if($scope.partner.sameAsContactPerson) { - $scope.partner.legal_representative_person = $scope.partner.contact_person; - $scope.partner.legal_representative_phone = $scope.partner.contact_phone; - $scope.partner.legal_representative_email = $scope.partner.contact_email; - $scope.partner.legal_representative_job = $scope.partner.contact_job; - $scope.partner.legal_representative_wechatid = $scope.partner.contact_wechatid; - } - } - - $scope.partner.marketingSameAsContact = false; - $scope.checkMarketingSameAsContact = function (){ - $scope.partner.marketingSameAsContact = !($scope.partner.marketingSameAsContact); - if($scope.partner.marketingSameAsContact) { - $scope.partner.marketing_person = $scope.partner.contact_person; - $scope.partner.marketing_phone = $scope.partner.contact_phone; - $scope.partner.marketing_email = $scope.partner.contact_email; - $scope.partner.marketing_job = $scope.partner.contact_job; - $scope.partner.marketing_wechatid = $scope.partner.contact_wechatid; - } - } - - $scope.partner.sameAsAddress=false; - $scope.sameAddress = function (){ - $scope.partner.sameAsAddress=!($scope.partner.sameAsAddress); - if($scope.partner.sameAsAddress) { - $scope.partner.registered_address = $scope.partner.address; - $scope.partner.registered_suburb = $scope.partner.suburb; - $scope.partner.registered_postcode = $scope.partner.postcode; - $scope.partner.registered_state = $scope.partner.state; - } - } - - $scope.listReferrers = function () { - $http.get('/sys/orgs/referrer').then(function (resp) { - $scope.referrers = resp.data; - }) - }; - $scope.listReferrers(); - - $scope.loadAlipayCategory = function () { - $http.get('/static/data/alipayMcc.json').then(function (resp) { - $scope.alipayMccCategory = resp.data; - }) - }; - $scope.loadAlipayCategory(); - $scope.loadJDindustry = function () { - $http.get('/static/data/jdindustry.json').then(function (resp) { - $scope.jdindustry = resp.data; - }) - }; - $scope.loadJDindustry(); - - $scope.loadLakalaPayindustry = function () { - $http.get('/static/data/lakalapayindustry.json').then(function (resp) { - $scope.lakalapayindustry = resp.data; - }) - }; - $scope.loadLakalaPayindustry(); - - $scope.loadLakalaPaySettle = function () { - $http.get('/static/data/lakalapaysettle.json').then(function (resp) { - $scope.lakalapaysettle = resp.data; - }) - }; - $scope.loadLakalaPaySettle(); - - $scope.loadLakalaPayGoods = function () { - $http.get('/static/data/lakalapaygoods.json').then(function (resp) { - $scope.lakalapaygoods = resp.data; - }) - }; - $scope.loadLakalaPayGoods(); - - $scope.loadRoyalpayindustry = function () { - $http.get('/static/data/royalpayindustry.json').then(function (resp) { - $scope.royalpayindustry = resp.data; - }) - }; - $scope.loadRoyalpayindustry(); - - $scope.loadHfindustry = function () { - $http.get('/static/data/hfindustry.json').then(function (resp) { - $scope.hfindustry = resp.data; - }) - }; - $scope.loadHfindustry(); - - $scope.onAlipayMccSelect = function (selectedItem) { - $scope.partner.alipay_category = selectedItem.label; - $scope.partner.alipayindustry = selectedItem.mccCode; - }; - $scope.onRoyalPayIndustrySelect = function (selectedItem) { - $scope.partner.royalpay_label = selectedItem.label; - $scope.partner.royalpayindustry = selectedItem.mccCode; - }; - $scope.onHfIndustrySelect = function (selectedItem) { - $scope.partner.hf_label = selectedItem.label; - $scope.partner.hfindustry = selectedItem.mccCode; - }; - - - $scope.updatePartner = function (form) { - if (form.$invalid) { - angular.forEach(form, function (item, key) { - if (key.indexOf('$') < 0) { - item.$dirty = true; - } - }); - return; - } - - if ($scope.partner.company_name.indexOf("Migration") != -1) { - alert("Company Name包含敏感词汇,请检查后重新提交!"); - return; - } - if ($scope.partner.company_phone.indexOf(' ') != -1) { - alert('Company Phone can not contain space character'); - return; - } - if ($scope.partner.contact_email.indexOf(' ') != -1) { - alert('Contact email Phone can not contain space character'); - return; - } - if ($scope.partner.suburb.indexOf(' ') != -1) { - alert('suburb can not contain two and more continuous space characters'); - return; - } - if ($scope.partner.client_pay_type.indexOf('2') >= 0) { - if (!$scope.partner.company_photo) { - alert('Shop Photo1 is necessary'); - return; - } - if (!$scope.partner.store_photo) { - alert('Shop Photo2 is necessary'); - return; - } - } - - if ($scope.partner.acn && $scope.partner.business_structure == 'Company') { - if ($scope.partner.acn.length != 9) { - alert('Acn is not valid'); - } - } - if ($scope.partner.referrer_id) { - $scope.referrers.forEach(function (e) { - if ($scope.partner.referrer_id == e.org_id) { - $scope.partner.referrer_name = e.name; - return; - } - }) - } - var content = ''; - if (!origin_referrer_id && $scope.partner.referrer_id) { - content = 'Update partner info successfully,But You Had add new Referrer,Please Change the BD Commission Proportion!'; - } - if ($scope.partner.client_pay_type.length == 0) { - alert('请选择商户支付场景') - return; - } - if ($scope.partner.client_pay_desc.length == 0) { - alert('请选择商户支付方式') - return; - } - if ($scope.partner.client_pay_type.indexOf('1') >= 0) { - if ($scope.partner.client_pay_desc.join(',').indexOf('10') < 0) { - alert("请检查线上支付场景是否已选择支付方式"); - return; - } - } - if ($scope.partner.client_pay_type.indexOf('2') >= 0) { - if ($scope.partner.client_pay_desc.join(',').indexOf('20') < 0) { - alert("请检查线下支付场景是否已选择支付方式"); - return; - } - } - if ($scope.partner.client_pay_desc.join(',').indexOf('203') >= 0) { - if ($scope.partner.client_pay_desc.join(',').indexOf('2030') < 0 && $scope.partner.client_pay_desc.join(',').indexOf('20399') < 0) { - alert("请检查线下支付是否已选择收银系统类型"); - return; - } - } - $scope.partner.client_pay_type = $scope.partner.client_pay_type.join(','); - $scope.partner.client_pay_desc = $scope.partner.client_pay_desc.join(','); - $http.put('/sys/partners/' + $scope.partner.client_moniker, $scope.partner).then(function () { - if (content != '') { - commonDialog.alert({ - title: 'Warning', - content: content, - type: 'error' - }); - } else { - commonDialog.alert({ - title: 'Success', - content: 'Update partner information successfully', - type: 'success' - }); - } - $scope.updateMerchantLocation(); - $scope.loadPartners(); - $state.go('^.detail', {clientMoniker: $scope.partner.client_moniker}, {reload: true}); + }) + }; + $scope.apply2makeAgreeFile = function () { + $http.get('/sys/partners/' + $scope.partner.client_moniker + '/make_agree_file').then(function () { + commonDialog.alert({ + title: 'Success!', + content: '已提交制作合同!', + type: 'success' + }); + $state.reload(); }, function (resp) { - commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}) - }); - }; - $scope.uploadLogo = function (file) { - if (file != null) { - if (file.size > 1 * 1024 * 1024) { - commonDialog.alert({title: 'Error', content: '文件大小不能超过1MB,请压缩后重试', type: 'error'}) - } else { - $scope.logoProgress = {value: 0}; - Upload.upload({ - url: '/attachment/files', - data: {file: file} - }).then(function (resp) { - delete $scope.logoProgress; - $scope.partner.logo_id = resp.data.fileid; - $scope.partner.logo_url = resp.data.url; - }, function (resp) { - delete $scope.logoProgress; - commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) - }, function (evt) { - $scope.logoProgress.value = parseInt(100 * evt.loaded / evt.total); - }) - } + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); } - }; + ); + }; - $scope.uploadShopPhoto = function (file) { - if (file != null) { - if (file.size > 2 * 1024 * 1024) { - commonDialog.alert({title: 'Error', content: '文件大小不能超过2MB,请压缩后重试', type: 'error'}) - } else { - $scope.shopPhotoProgress = {value: 0}; - Upload.upload({ - url: '/attachment/files', - data: {file: file} - }).then(function (resp) { - delete $scope.shopPhotoProgress; - $scope.partner.company_photo = resp.data.url; - }, function (resp) { - delete $scope.shopPhotoProgress; - commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) - }, function (evt) { - $scope.shopPhotoProgress.value = parseInt(100 * evt.loaded / evt.total); - }) + $scope.commit2GreenChannel = function () { + commonDialog.confirm({ + title: 'Audit Partner', + content: 'Are you sure to mark partner ' + $scope.partner.company_name + ' Green Channel?' + }).then(function () { + $http.put('/sys/partners/' + $scope.partner.client_moniker + '/compliance/green_channel').then(function () { + commonDialog.alert({ + title: 'Success', + content: 'Commit to Green Channel successfully', + type: 'success' + }); + $state.reload(); + }, function (resp) { + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); + }) + + }) + }; + + $scope.markAuditEmail = function () { + commonDialog.confirm({ + title: 'Warning', + content: 'Make sure you have send the email to client.' + }).then(function () { + $http.put('/sys/partners/' + $scope.partner.client_moniker + '/audit/email_sending_status').then(function () { + $state.reload(); + }, function (resp) { + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); + }) + }) + }; + $scope.resendApproveEmail = function () { + commonDialog.confirm({ + title: 'Warning', + content: 'This operation will reset the password of admin user. Are you sure this email is correct ? Or you may update this information first.' + }).then(function () { + $http.put('/sys/partners/' + $scope.partner.client_moniker + '/audit/send_email').then(function () { + $state.reload(); + }, function (resp) { + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); + }) + }) + }; + $scope.editBDUser = function () { + $uibModal.open({ + templateUrl: '/static/payment/partner/templates/bd_user_choose_dialog.html', + controller: 'partnerChooseBDUserDialogCtrl', + resolve: { + bdUsers: ['$http', function ($http) { + return $http.get('/sys/manager_accounts/roles/bd_user'); + }], + partner: function () { + return $scope.partner; + }, + type: function () { + return 'edit'; } } - }; - - $scope.uploadStorePhoto = function (file) { - if (file != null) { - if (file.size > 2 * 1024 * 1024) { - commonDialog.alert({title: 'Error', content: '文件大小不能超过2MB,请压缩后重试', type: 'error'}) - } else { - $scope.storePhotoProgress = {value: 0}; - Upload.upload({ - url: '/attachment/files', - data: {file: file} - }).then(function (resp) { - delete $scope.storePhotoProgress; - $scope.partner.store_photo = resp.data.url; - }, function (resp) { - delete $scope.storePhotoProgress; - commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) - }, function (evt) { - $scope.storePhotoProgress.value = parseInt(100 * evt.loaded / evt.total); - }) + }).result.then(function () { + $state.reload(); + }) + }; + $scope.bindBDUser = function () { + $uibModal.open({ + templateUrl: '/static/payment/partner/templates/bd_user_choose_dialog.html', + controller: 'partnerChooseBDUserDialogCtrl', + resolve: { + bdUsers: ['$http', function ($http) { + return $http.get('/sys/manager_accounts/roles/bd_user'); + }], + partner: function () { + return $scope.partner; + }, + type: function () { + return 'add'; } } - }; - - $scope.getMerchantLocation = function () { - $http.get('/sys/partners/' + $scope.partner.client_moniker + '/location').then(function (resp) { - $scope.merchant_location = resp.data; - }); - }; - $scope.getMerchantLocation(); + }).result.then(function () { + $state.reload(); + }) + }; - $scope.updateMerchantLocation = function () { - var params = window.frames['merchant_detail'].merchant_location; - if (params) { - $http.put('/sys/partners/modify/' + $scope.partner.client_moniker + '/location', params).then(function () { + $scope.configMasterMerchant = function () { + commonDialog.inputText({title: 'Input Master Merchant Code'}).then(function (text) { + $http.put('/sys/partners/' + $scope.partner.client_moniker + '/master_configuration', {master_merchant: text}).then(function () { + commonDialog.alert({title: 'Success', content: "Master Merchant Code:" + text, type: 'success'}); + }, function (resp) { + commonDialog.alert({ + title: 'Config Master Merchant Failed', + content: resp.data.message, + type: 'error' }); + }) + }) + }; + + $scope.getMerchantLocation = function () { + $http.get('/sys/partners/' + $scope.partner.client_moniker + '/location').then(function (resp) { + $scope.merchant_location = resp.data; + }); + }; + $scope.getMerchantLocation(); + + + $scope.complianceCheck = function () { + if (!$rootScope.complianceCheck) { + $rootScope.complianceCheck = {}; + } + $rootScope.complianceCheck.client_id = $scope.partner.client_id; + $rootScope.complianceCheck.clientInfo = true; + }; + $scope.complianceChangeCheck = function () { + if ($rootScope.complianceCheck) { + if ($scope.partner.client_id != $rootScope.complianceCheck.client_id) { + delete $rootScope.complianceCheck; } } - }]); + }; + $scope.complianceChangeCheck(); + + $scope.changeWechatCompliance = function () { + if (!$scope.partner) { + return; + } + if (!$state.is('partners.detail')) { + $scope.init.wechat_compliance = false; + return; + } + if (!$scope.init.wechat_compliance) { + $scope.init.wechat_compliance = true; + return; + } + $http.put('/sys/partners/' + $scope.partner.client_moniker + '/wechat_compliance_permission', {allow: $scope.partner.wechat_compliance}).then(function () { + + }, function (resp) { + commonDialog.alert({ + title: 'failed to change wechat_compliance permission status', + content: resp.data.message, + type: 'error' + }) + }) + }; + $scope.changeLocalMerchant = function () { + if (!$scope.partner) { + return; + } + if (!$state.is('partners.detail')) { + $scope.init.local_merchant = false; + return; + } + if (!$scope.init.local_merchant) { + $scope.init.local_merchant = true; + return; + } + $http.put('/sys/partners/' + $scope.partner.client_moniker + '/local_merchant_permission', {allow: $scope.partner.local_merchant}).then(function () { + + }, function (resp) { + commonDialog.alert({ + title: 'failed to change local_merchant permission status', + content: resp.data.message, + type: 'error' + }) + }) + }; + + $scope.removeSub = function () { + $http.delete('/sys/partners/unsub/' + $scope.partner.client_moniker).then(function (resp) { + $state.reload(); + }); + }; + $scope.addSub = function () { + $http.put('/sys/partners/unsub/' + $scope.partner.client_moniker).then(function (resp) { + $state.reload(); + }); + }; + }]); app.controller('partnerPaymentInfoCtrl', ['$scope', '$http', '$state', 'commonDialog', '$uibModal', '$sce', function ($scope, $http, $state, commonDialog, $uibModal, $sce) { $scope.convertExtParams = []; $scope.copyHfLink = function () { @@ -4114,7 +3261,14 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter }; $scope.listRedpackLogs(1); }]); - app.controller('partnerAuthFileCtrl', ['$scope', '$http', '$rootScope', 'commonDialog', '$state', 'Upload', 'file', function ($scope, $http, $rootScope, commonDialog, $state, Upload, file) { + app.controller('partnerAuthFileCtrl', ['$scope', '$http', '$rootScope', 'commonDialog', '$state', function ($scope, $http, $rootScope, commonDialog, $state) { + if ($scope.partner.client_type=='card-payment'){ + $state.go('partners.detail.files.MW_files'); + }else { + $state.go('partners.detail.files.CP_files'); + } + }]); + app.controller('partnerCPAuthFileCtrl', ['$scope', '$http', '$rootScope', 'commonDialog', '$state', 'Upload', 'file', function ($scope, $http, $rootScope, commonDialog, $state, Upload, file) { $scope.id_info_form = {edit: false}; $scope.file = file.data || {}; //audit files @@ -4366,7 +3520,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); }) }) -}; + }; $scope.updateFile = function () { @@ -4406,7 +3560,6 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter $scope.complianceChangeCheck(); }]); - app.controller('partnerMWAuthFileCtrl', ['$scope', '$http', '$rootScope', 'commonDialog', '$state', 'Upload', 'file', function ($scope, $http, $rootScope, commonDialog, $state, Upload, file) { $scope.id_info_form = {edit: false}; $scope.file = file.data || {}; diff --git a/src/main/ui/static/payment/partner/templates/add_partner.html b/src/main/ui/static/payment/partner/templates/add_partner.html index 6ebd8ff88..098a270da 100644 --- a/src/main/ui/static/payment/partner/templates/add_partner.html +++ b/src/main/ui/static/payment/partner/templates/add_partner.html @@ -16,6 +16,13 @@ background-color: #f7bf90; border-color: #adadad; } + .form-control-float { + float: left; + width: 93%; !important; + } + .form-control-span{ + height: 34px; + }

New Partner

@@ -26,11 +33,25 @@
  • New Partner
  • -
    +
    Partner Basic Information
    @@ -112,21 +133,40 @@
    -
    -
    + +
    + +
    +

    Required + Field

    +

    Less + Than 19 + Characters(including symbols and spaces)

    +
    +
    +
    +
    @@ -148,7 +188,7 @@
    -
    @@ -176,31 +216,19 @@
    - - - - - - - - - - - - - -
    - + ng-if="partner.business_structure != 'Company' || partner.client_type=='card-payment' || partner.client_type=='all'"> +
    +

    Required + Field

    Less Than 20 Characters(including symbols and spaces)

    @@ -209,7 +237,7 @@
    + ng-if="partner.business_structure == 'Company' && partner.client_type!='card-payment'">
    - - - - - - - - - - - - - - - - -
    -
    +
    @@ -296,7 +298,6 @@ Than 11 Characters

    -
    @@ -353,7 +354,7 @@ ng-click="toggleClientPayType('1')"> 线上 -
    -
    +
    @@ -420,7 +421,7 @@
    -
    +
    @@ -491,7 +492,7 @@
    -
    +
    1:  @@ -503,9 +504,9 @@ - +
    @@ -518,16 +519,48 @@ - +
    +
    + +
    + + $ +
    +

    Required + Field

    +
    +
    +
    +
    + +
    + + $ +
    +

    Required + Field

    +
    +
    +
    -
    +
    Alipay Information  (Optional)
    @@ -669,16 +702,6 @@ Characters(including symbols and spaces)

    - -
    - -
    - -
    -
    -
    @@ -707,16 +729,26 @@ maxlength="50">
    + +
    + +
    + +
    +
    -
    - -
    + +
    +
    -
    -

    +
    +
      Legal Representative
    @@ -791,7 +823,7 @@
    + E-mail
    -
    -
      Marketing Person
    -
    +
    +
      Marketing Person
    +
    @@ -1195,105 +1227,6 @@
    - - -
    Industry @@ -1318,7 +1251,7 @@
    -
    @@ -1337,7 +1270,7 @@
    -
    @@ -1356,6 +1289,44 @@
    + +
    + +
    + +
    +

    Required + Field

    +
    +
    +
    +
    + +
    + + + + + + +
    +
    diff --git a/src/main/ui/static/payment/partner/templates/partner_auth_files.html b/src/main/ui/static/payment/partner/templates/partner_auth_files.html index 12bf85c97..c77dffeed 100644 --- a/src/main/ui/static/payment/partner/templates/partner_auth_files.html +++ b/src/main/ui/static/payment/partner/templates/partner_auth_files.html @@ -3,366 +3,18 @@ width: 100%; } -
    -
    Audit Files     - - 一键下载 - +
    + -
    -
    -
    -

    - ID描述信息 - - -

    -
    -
    -
    - -
    -
    - -
    -
    -
    -
    - -
    - - - - - -
    -
    -
    - -
    -
    - -
    -
    -
    -
    - -
    -
    - {{file.id_type}} -
    -
    -
    -
    - -
    - - - - - -
    -
    -
    - -
    -
    - -
    -
    -
    -
    -
    - -
    -
    - -
    -
    - - -
    - - - - - - - - - -
    1 - - - - -
    - - -
    -
    -
    -

    Example:请保证图片信息清晰可见,如下图

    - -
    -
    -
    - -
    - -
    -
    - - -
    - - - - - - - -
    1 - - - - -
    -
    -
    -
    -
    -

    Example:公司请提供以下文件图片

    - - -
    -
    -

    sole trade(个体户),partnership(合伙),trust(信托)请在http://abr.business.gov.au,将查询结果截图上传

    - -
    -
    -
    -
    - -
    - -
    -
    - - -
    - - - - - - - - -
    1 - - - - -
    -
    -
    -
    -
    -

    Example:请保证图片(护照或驾照)信息清晰可见,如下图

    - -
    -
    -
    -
    - -
    -
    -
    -
    - -
    -
    - -
    -
    - - -
    - - - - - - - - -
    1 - - - - -
    -
    -
    -
    -

    Example:请保证图片信息清晰可见,如下图

    - -
    -
    -
    -
    - -
    -
    - -
    -
    - - -
    - - - - - - - - -
    1 - - - - -
    -
    -
    -
    -

    Example:请保证图片信息清晰可见,如下图

    - -
    -
    -
    -
    - -
    - -
    -
    - -

    - One utility bill (water, electricity or gas) that shows the residential address (*Mandatory if your uploaded ID is a passport)
    - 一份显示常住居所地址的账单(水费、电费或煤气费)(*必须上传 - 如您上传的ID是护照)
    -

    - -
    - - - - - - - - -
    1 - - - -
    -
    -
    -
    -
    -

    Example:请提供水电煤账单文件图片,如示例 - 水费.png -
    电费.jpg -

    -

    - 煤气.png -

    -
    -
    -
    -
    -
    -
    -
    - check -
    -
    - - - - +
    diff --git a/src/main/ui/static/payment/partner/templates/partner_cp_auth_files.html b/src/main/ui/static/payment/partner/templates/partner_cp_auth_files.html new file mode 100644 index 000000000..2d9035b04 --- /dev/null +++ b/src/main/ui/static/payment/partner/templates/partner_cp_auth_files.html @@ -0,0 +1,363 @@ + + +
    Audit Files     + + 一键下载 + +
    +
    +
    +
    +

    + ID描述信息 + + +

    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    + + + + + +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + {{file.id_type}} +
    +
    +
    +
    + +
    + + + + + +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + + +
    + + + + + + + + + +
    1 + + + + +
    + + +
    +
    +
    +

    Example:请保证图片信息清晰可见,如下图

    + +
    +
    +
    + +
    + +
    +
    + + +
    + + + + + + + +
    1 + + + + +
    +
    +
    +
    +
    +

    Example:公司请提供以下文件图片

    + + +
    +
    +

    sole trade(个体户),partnership(合伙),trust(信托)请在http://abr.business.gov.au,将查询结果截图上传

    + +
    +
    +
    +
    + +
    + +
    +
    + + +
    + + + + + + + + +
    1 + + + + +
    +
    +
    +
    +
    +

    Example:请保证图片(护照或驾照)信息清晰可见,如下图

    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + + +
    + + + + + + + + +
    1 + + + + +
    +
    +
    +
    +

    Example:请保证图片信息清晰可见,如下图

    + +
    +
    +
    +
    + +
    +
    + +
    +
    + + +
    + + + + + + + + +
    1 + + + + +
    +
    +
    +
    +

    Example:请保证图片信息清晰可见,如下图

    + +
    +
    +
    +
    + +
    + +
    +
    + +

    + One utility bill (water, electricity or gas) that shows the residential address (*Mandatory if your uploaded ID is a passport)
    + 一份显示常住居所地址的账单(水费、电费或煤气费)(*必须上传 - 如您上传的ID是护照)
    +

    + +
    + + + + + + + + +
    1 + + + +
    +
    +
    +
    +
    +

    Example:请提供水电煤账单文件图片,如示例 + 水费.png +
    电费.jpg +

    +

    + 煤气.png +

    +
    +
    +
    +
    +
    +
    +
    + check +
    diff --git a/src/main/ui/static/payment/partner/templates/partner_detail.html b/src/main/ui/static/payment/partner/templates/partner_detail.html index bb9a6182d..5514efada 100644 --- a/src/main/ui/static/payment/partner/templates/partner_detail.html +++ b/src/main/ui/static/payment/partner/templates/partner_detail.html @@ -277,9 +277,6 @@
  • Compliance Files
  • -
  • - Merchant Warrior Compliance Files -
  • diff --git a/src/main/ui/static/payment/partner/templates/partner_edit.html b/src/main/ui/static/payment/partner/templates/partner_edit.html index d9a07d714..0cecd2c54 100644 --- a/src/main/ui/static/payment/partner/templates/partner_edit.html +++ b/src/main/ui/static/payment/partner/templates/partner_edit.html @@ -10,6 +10,13 @@ background-color: #f7bf90; border-color: #adadad; } + .form-control-float { + float: left; + width: 93%; !important; + } + .form-control-span{ + height: 34px; + }

    @@ -26,6 +33,21 @@
    +
    Partner Basic Information
    @@ -82,7 +104,7 @@
    - +
    @@ -93,7 +115,7 @@
    -
    @@ -111,9 +133,7 @@
    -
    -
    @@ -162,7 +182,7 @@
    -
    @@ -181,8 +201,24 @@
    - -
    + +
    + +
    +

    Required + Field

    +

    Less + Than 19 + Characters(including symbols and spaces)

    +
    +
    +
    +
    @@ -206,20 +242,6 @@
    - - - - - - - - - - - - - -
    @@ -319,7 +341,7 @@ ng-click="toggleClientPayType('1')"> 线上 -
    -
    +
    @@ -386,7 +408,7 @@
    -
    +
    @@ -457,7 +479,7 @@
    -
    +
    1:  @@ -488,11 +510,43 @@
    +
    + +
    + + $ +
    +

    Required + Field

    +
    +
    +
    +
    + +
    + + $ +
    +

    Required + Field

    +
    +
    +
    -
    +
    Alipay Information   (Optional)
    @@ -578,16 +632,6 @@ Characters(including symbols and spaces)

    - -
    - -
    - -
    -
    + +
    + +
    + +
    +
    -
    +
    @@ -729,8 +783,8 @@
    -
      Marketing Person
    -
    +
      Marketing Person
    +
    @@ -1080,81 +1134,6 @@
    - -
    Industry
    @@ -1178,7 +1157,7 @@
    -
    @@ -1197,7 +1176,7 @@
    -
    @@ -1216,6 +1195,42 @@
    +
    + +
    + +
    +

    Required + Field

    +
    +
    +
    +
    + +
    + + + + + + +
    diff --git a/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html b/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html index 079916613..371b91dbb 100644 --- a/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html +++ b/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html @@ -3,82 +3,81 @@ width: 100%; } -
    -
    Audit Files     - - 一键下载 - -
    -
    -
    -
    -

    - Merchant Warrior商户风险评级 - - -

    -
    -
    -
    - -
    -
    - -
    +
    Audit Files     + + 一键下载 + +
    +
    +
    +
    +

    + Merchant Warrior商户风险评级 + + +

    +
    +
    +
    + +
    +
    +
    -
    - -
    -
    - -
    +
    +
    + +
    +
    +
    -
    - -
    -
    - 低风险 - 中风险 - 高风险 -
    +
    +
    + +
    +
    + 低风险 + 中风险 + 高风险
    -
    - -
    -
    - -
    +
    +
    + +
    +
    +
    -
    -
    - -
    -
    - - - -
    - - + + +
    + +
    +
    + + + +
    + +
    -
    @@ -87,108 +86,107 @@
    + +
    +
    + +
    + +
    +
    + + +
    + + + + + + +
    + + +
    +
    +
    + +
    +
    + + + +
    + + + + + +
    + + +
    +
    +
    + +
    - +
    - +
    - + -
    - + +
    +
    +
    - +
    - - -
    - - - - - -
    - - -
    -
    -
    - -
    -
    - -
    -
    - - - -
    - - - - - - -
    - - -
    -
    -
    -
    - -
    -
    - -
    -
    - - - -
    - - - - - - -
    - - -
    + +
    + + + + + + +
    + + +
    -
    +
    From a382441bf29473ee48aaed62011de2642eb911b5 Mon Sep 17 00:00:00 2001 From: dulingling Date: Mon, 27 Apr 2020 14:55:57 +0800 Subject: [PATCH 08/40] =?UTF-8?q?Upd:=E5=A2=9E=E5=8A=A0=E5=8D=A1=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E5=90=88=E8=A7=84=E6=B5=81=E7=A8=8B=EF=BC=8CBD?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E8=B5=84=E6=96=99=EF=BC=8C=E5=90=88=E8=A7=84?= =?UTF-8?q?=E9=80=9A=E8=BF=87=EF=BC=8C=E5=90=88=E8=A7=84=E6=89=93=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/ClientAuditProcessMapper.java | 2 +- .../mappers/system/ClientCardFlowMapper.java | 31 ++ .../manage/merchants/beans/PartnerQuery.java | 12 + .../manage/merchants/core/ClientManager.java | 12 + .../core/impls/ClientManagerImpl.java | 443 ++++++++++++++---- .../web/PartnerManageController.java | 21 + .../manage/mappers/system/ClientMapper.xml | 18 + .../static/payment/partner/partner-manage.js | 95 ++++ .../partner/templates/partner_detail.html | 180 ++++++- .../payment/partner/templates/partners.html | 54 ++- 10 files changed, 742 insertions(+), 126 deletions(-) create mode 100644 src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientCardFlowMapper.java diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientAuditProcessMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientAuditProcessMapper.java index 9ebfae667..c277cfa4b 100644 --- a/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientAuditProcessMapper.java +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientAuditProcessMapper.java @@ -20,5 +20,5 @@ public interface ClientAuditProcessMapper { int update(JSONObject partner); @AutoSql(SqlType.SELECT) - PageList getAuditLog(@Param("client_id") int client_id, PageBounds pagination); + PageList getAuditLog(@Param("client_id") int client_id, @Param("type") int type, PageBounds pagination); } diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientCardFlowMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientCardFlowMapper.java new file mode 100644 index 000000000..485ef152c --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientCardFlowMapper.java @@ -0,0 +1,31 @@ +package au.com.royalpay.payment.manage.mappers.system; + +import com.alibaba.fastjson.JSONObject; +import com.github.miemiedev.mybatis.paginator.domain.PageBounds; +import com.github.miemiedev.mybatis.paginator.domain.PageList; +import com.yixsoft.support.mybatis.autosql.annotations.AdvanceSelect; +import com.yixsoft.support.mybatis.autosql.annotations.AutoMapper; +import com.yixsoft.support.mybatis.autosql.annotations.AutoSql; +import com.yixsoft.support.mybatis.autosql.annotations.SqlType; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator; + +import java.util.Date; +import java.util.List; + +/** + * Created by dulingling on 2020-04-26. + */ +@AutoMapper(tablename = "sys_clients_card_flow", pkName = "client_id", keyGenerator = Jdbc3KeyGenerator.class) +public interface ClientCardFlowMapper { + @AutoSql(SqlType.SELECT) + JSONObject findClient(@Param("client_id") int clientId); + + @AutoSql(SqlType.INSERT) + void save(JSONObject partner); + + @AutoSql(SqlType.UPDATE) + int update(JSONObject partner); + +} diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/beans/PartnerQuery.java b/src/main/java/au/com/royalpay/payment/manage/merchants/beans/PartnerQuery.java index 56e39c370..4f2503bbd 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/beans/PartnerQuery.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/beans/PartnerQuery.java @@ -51,6 +51,7 @@ public class PartnerQuery { private boolean bd_upload_material = false; private boolean is_valid = false; private String merchant_id; + private boolean card_approving = false; public String getClient_moniker() { return StringUtils.isEmpty(client_moniker) ? null : client_moniker; @@ -120,6 +121,9 @@ public class PartnerQuery { if (approving) { param.put("approving", true); } + if(card_approving){ + param.put("card_approving",true); + } if (org_id != null) { param.put("org_id", org_id); } @@ -472,4 +476,12 @@ public class PartnerQuery { public void setSuburb(String suburb) { this.suburb = suburb; } + + public boolean isCard_approving() { + return card_approving; + } + + public void setCard_approving(boolean card_approving) { + this.card_approving = card_approving; + } } diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java index 18eca9b1c..d95488795 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java @@ -81,6 +81,9 @@ public interface ClientManager { @Transactional(noRollbackFor = EmailException.class) void auditClient(JSONObject manager, String clientMoniker, int pass); + @Transactional(noRollbackFor = EmailException.class) + void auditCardClient(JSONObject manager, String clientMoniker, int pass); + @Transactional(noRollbackFor = EmailException.class) void auditClientGreenChannel(JSONObject manager, String clientMoniker); @@ -299,6 +302,13 @@ public interface ClientManager { void commitToDoAgreeFile(String clientMoniker, JSONObject manager); + /** + * 提交资料,申请卡支付 + * @param clientMoniker + * @param manager + */ + void commitToDoCardAgreeFile(String clientMoniker, JSONObject manager); + void commitToGreenChannel(String clientMoniker, JSONObject manager); void changePaymentPage(JSONObject manager, String clientMoniker, String paypad_version); @@ -335,6 +345,8 @@ public interface ClientManager { void refusePartner(String clientMoniker, JSONObject manager, String refuse_remark); + void cardRefusePartner(String clientMoniker, JSONObject manager, String refuse_remark); + JSONArray getAllClientIds(int clientId); void updateAppClient(JSONObject account, int client_id, AppClientBean appClientBean); diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index b77ff85ce..3295258dc 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -328,6 +328,10 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid private RPayMerchantMapper rPayMerchantMapper; @Resource private SysClientUpayProfileMapper sysClientUpayProfileMapper; + @Resource + private ClientCardFlowMapper clientCardFlowMapper; + + @Resource private SmsSender smsSender; private static final String SOURCE_AGREE_FILE = "source_agree_file"; @@ -434,7 +438,9 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } client.putAll(clientConfig); JSONObject upayInfo = sysClientUpayProfileMapper.findInfo(client.getIntValue("client_id")); - client.putAll(upayInfo); + if(null != upayInfo){ + client.putAll(upayInfo); + } client.put("unsubscribe", mailUnsubMapper.findOneByClientMoniker(clientMoniker) == null ? false : true); client.put("show_all_permission", true); int role = manager != null ? manager.getIntValue("role") : 0; @@ -488,12 +494,24 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid client.put("min_customer_surcharge_rate", client.getBigDecimal("rate_value").add(new BigDecimal("0.1"))); } - // 商户审核过程日志 - PageList audit_logs = clientAuditProcessMapper.getAuditLog(client.getIntValue("client_id"), + // 商户跨境支付审核过程日志 + PageList audit_logs = clientAuditProcessMapper.getAuditLog(client.getIntValue("client_id"),1, new PageBounds(Order.formString("create_time"))); if (audit_logs != null && !audit_logs.isEmpty()) { client.put("audit_logs", audit_logs); } + //商户卡支付审核过程日志 + PageList audit_card_logs = clientAuditProcessMapper.getAuditLog(client.getIntValue("client_id"),2, + new PageBounds(Order.formString("create_time"))); + if (audit_card_logs != null && !audit_card_logs.isEmpty()) { + client.put("audit_card_logs", audit_card_logs); + } + + //插入卡支付审核状态 + JSONObject cardFlowInfo = clientCardFlowMapper.findClient(client.getInteger("client_id")); + if(null != cardFlowInfo){ + client.put("card_flow_info",cardFlowInfo); + } //HF支付链接二维码 if (client.getString("hf_pay_url") != null) { @@ -568,6 +586,10 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid partner.put("expiry_time", DateUtils.addDays(partner.getDate("approve_time"), authDays)); partner.put("pass_timeout", DateUtils.addDays(partner.getDate("approve_time"), authDays).compareTo(new Date()) < 0); } + JSONObject cardFlowInfo = clientCardFlowMapper.findClient(partner.getInteger("client_id")); + if(null != cardFlowInfo){ + partner.put("card_approve_flow_info",cardFlowInfo); + } } return PageListUtils.buildPageListResult(partners); } @@ -1161,30 +1183,71 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid clientModifySupport.processClientModify(auditModify); sendCommissionWechatMessage(client);// wxMessage if (pass == 1) { - createKycAuthStatus(manager,client); + createKycAuthStatus(manager, client); clientModifySupport.processClientConfigModify(new SwitchPermissionModify(manager, clientMoniker, "skip_clearing", false)); if (client.getIntValue("source") == 4 || client.getIntValue("source") == 5) { List accounts = clientAccountMapper.listAdminAccounts(client.getIntValue("client_id")); JSONObject account = accounts.get(0); sendInitEmail(client, account.getString("username"), "*****"); // sendInitEmail(manager, client, account.getString("username"), "*****"); - saveClientAuditProcess(client.getIntValue("client_id"), open_status, 5, "合规通过", manager); + saveClientAuditProcess(client.getIntValue("client_id"), open_status, 5, "合规通过", manager,1); clientModifySupport.processClientConfigModify(new SwitchPermissionModify(manager, clientMoniker, "skip_clearing", false)); clientModifySupport.processClientConfigModify(new SwitchPermissionModify(manager, clientMoniker, "common_sub_merchant_id", false)); gatewayMerchantApply.notifyOrgMerchantStatus(client); } else if (checkGreenChannel && client.getIntValue("open_status") == 5) { // 绿色通道通过后不发邮件 logger.info("PASS 绿色通道:" + clientMoniker); - saveClientAuditProcess(client.getIntValue("client_id"), open_status, 5, "合规通过", manager); + saveClientAuditProcess(client.getIntValue("client_id"), open_status, 5, "合规通过", manager,1); } else { initAdminUserAndSendEmail(manager, clientMoniker, client); - saveClientAuditProcess(client.getIntValue("client_id"), open_status, 5, "合规通过", manager); + saveClientAuditProcess(client.getIntValue("client_id"), open_status, 5, "合规通过", manager,1); } } clientInfoCacheSupport.clearClientCache(client.getIntValue("client_id")); } - private void createKycAuthStatus(JSONObject manager,JSONObject client){ + @Override + public void auditCardClient(JSONObject manager, String clientMoniker, int pass) { + JSONObject client = getClientInfoByMoniker(clientMoniker); + if (client == null) { + throw new InvalidShortIdException(); + } + //检查商户是否进入平台黑名单 + int clientId = client.getIntValue("client_id"); + isRiskyMerchant(client, clientBankAccountMapper.clientBankAccounts(clientId).get(0)); + + if (client.getString("sub_merchant_id") == null || client.getString("sub_merchant_id").equals("")) { + throw new BadRequestException("该商户未设置微信 Sub Merchant ID!"); + } + JSONObject cardFlowInfo = clientCardFlowMapper.findClient(clientId); + client.putAll(clientConfigService.find(client.getIntValue("client_id"))); + Integer open_status_to = cardFlowInfo != null? cardFlowInfo.getIntValue("open_status") : null; + cardFlowInfo.put("open_status",5); + cardFlowInfo.put("approve_result",1); + clientCardFlowMapper.update(cardFlowInfo); + sendCardCommissionWechatMessage(client);// wxMessage + if (pass == 1) { + createKycAuthStatus(manager, client); + clientModifySupport.processClientConfigModify(new SwitchPermissionModify(manager, clientMoniker, "skip_clearing", false)); + if (client.getIntValue("source") == 4 || client.getIntValue("source") == 5) { + List accounts = clientAccountMapper.listAdminAccounts(client.getIntValue("client_id")); + JSONObject account = accounts.get(0); + //TODO 发送卡支付开通邮件 1.判断商户是否已开通跨境支付,若没有开通,init账号 +// sendInitEmail(client, account.getString("username"), "*****"); + saveClientAuditProcess(client.getIntValue("client_id"), open_status_to, 5, "合规通过", manager,2); + + clientModifySupport.processClientConfigModify(new SwitchPermissionModify(manager, clientMoniker, "skip_clearing", false)); +// gatewayMerchantApply.notifyOrgMerchantStatus(client); + } else { + //TODO 发送卡支付开通邮件 1.判断商户是否已开通跨境支付,若没有开通,init账号 +// initAdminUserAndSendEmail(manager, clientMoniker, client); + saveClientAuditProcess(client.getIntValue("client_id"), open_status_to, 5, "合规通过", manager,2); + } + } + clientInfoCacheSupport.clearClientCache(client.getIntValue("client_id")); + } + + private void createKycAuthStatus(JSONObject manager, JSONObject client) { JSONObject compliance = clientComplianceCompanyMapper.findKycFileByClientId(client.getIntValue("client_id")); if (compliance != null) { compliance.put("client_id", client.getIntValue("client_id")); @@ -1227,7 +1290,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid throw new BadRequestException("该商户未设置微信 Sub Merchant ID!"); } clientModifySupport.processClientModify(new GreenChannelModify(manager, clientMoniker, manager.getString("manager_id"))); - saveClientAuditProcess(client.getIntValue("client_id"), 10, 1, "绿色通道申请通过", manager); + saveClientAuditProcess(client.getIntValue("client_id"), 10, 1, "绿色通道申请通过", manager,1); sendCommissionWechatMessage(client); initAdminUserAndSendEmail(manager, clientMoniker, client); } @@ -2051,7 +2114,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid clientRateMapper.updateConfig(rateLog); } if (StringUtils.equalsIgnoreCase("rpaypmt_card", config.getString("type"))) { - JSONObject extRateParams = new JSONObject(){{ + JSONObject extRateParams = new JSONObject() {{ put("domestic_rate_value", config.getBigDecimal("rate_value")); put("overseas_rate_value", config.getJSONObject("ext_rates").getBigDecimal("international_rate_value")); }}; @@ -2088,7 +2151,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid int clientId = client.getIntValue("client_id"); JSONObject changeRate = merchantInfoProvider.clientCurrentRate(clientId, new Date(), "Wechat"); int cleanDays = changeRate.getIntValue("clean_days"); - if (cleanDays != client.getIntValue("clean_days") && StringUtils.equalsIgnoreCase("Wechat",config.getRateName())) { + if (cleanDays != client.getIntValue("clean_days") && StringUtils.equalsIgnoreCase("Wechat", config.getRateName())) { clientModifySupport.processClientConfigModify(new ClearDaysModify(manager, clientMoniker, cleanDays)); } // clientMapper.updateCleanDays(clientId, config.getCleanDays()); @@ -2127,7 +2190,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid checkOrgPermission(manager, client); List listChildClients = clientMapper.listChildClients(client.getIntValue("client_id")); JSONObject mchConfig = merchantInfoProvider.getMchExtParams(client.getIntValue("client_id")); - if(mchConfig.getBooleanValue("hide_sub_mch")){ + if (mchConfig.getBooleanValue("hide_sub_mch")) { return new ArrayList<>(); } if (mchConfig.getBooleanValue("level3_mch_config")) { @@ -2145,7 +2208,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } @Override - public JSONObject listSubClientsByPage(JSONObject manager, String clientMoniker,String searchText, int page) { + public JSONObject listSubClientsByPage(JSONObject manager, String clientMoniker, String searchText, int page) { JSONObject client = getClientInfoByMoniker(clientMoniker); if (client == null) { throw new InvalidShortIdException(); @@ -2153,7 +2216,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid checkOrgPermission(manager, client); PageBounds pageBounds; - pageBounds= new PageBounds(page, 20, Order.formString("create_time.desc")); + pageBounds = new PageBounds(page, 20, Order.formString("create_time.desc")); JSONObject params = new JSONObject() {{ put("parent_client_id", client.getIntValue("client_id")); }}; @@ -2753,7 +2816,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid if (client_ids != null) { params.put("client_ids", Arrays.asList(client_ids)); params.remove("client_id"); - }else { + } else { queryModifyClientIds(client.getIntValue("client_id"), params); } List deviceIds = clientDeviceMapper.listClientDeviceIds(params); @@ -3304,7 +3367,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } if (manager != null) { - saveClientAuditProcess(client.getIntValue("client_id"), 1, 2, "Compliance合同制作中", manager); + saveClientAuditProcess(client.getIntValue("client_id"), 1, 2, "Compliance合同制作中", manager,1); } } } @@ -3321,7 +3384,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } client.put("open_status", 3); clientModifySupport.processClientModify(new OpenStatusModify(manager, clientMoniker, 3)); - saveClientAuditProcess(client.getIntValue("client_id"), 2, 3, "合同制作完成,等待BD处理", manager); + saveClientAuditProcess(client.getIntValue("client_id"), 2, 3, "合同制作完成,等待BD处理", manager,1); // sendAgreeFileMsgToBD(client,null); sendCommissionWechatMessage(client); } @@ -3514,7 +3577,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid if (client == null) { throw new InvalidShortIdException(); } - clientModifySupport.processClientModify( new SwitchAllowSurchargeCreditModify(manager, clientMoniker, "enable_presettle", presettle)); + clientModifySupport.processClientModify(new SwitchAllowSurchargeCreditModify(manager, clientMoniker, "enable_presettle", presettle)); } @Override @@ -3567,7 +3630,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid throw new InvalidShortIdException(); } params.put("display_name", manager.getString("display_name")); - clientApproveIdInfo(params,client); + clientApproveIdInfo(params, client); } @Override @@ -3659,7 +3722,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid @Override public JSONObject getAllAuthFiles(JSONObject manager, String clientMoniker) { JSONObject client = getClientInfoByMoniker(clientMoniker); - String[] fileKeys = {"client_bank_file", "client_company_file", "client_id_file", "client_agree_file", "client_apply_file","kyc_utility_bill_file"}; + String[] fileKeys = {"client_bank_file", "client_company_file", "client_id_file", "client_agree_file", "client_apply_file", "kyc_utility_bill_file"}; if (client == null) { throw new InvalidShortIdException(); } @@ -3714,7 +3777,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid List clientFiles = clientFilesMapper.findClientFile(client.getIntValue("client_id")); JSONObject fileJson = new JSONObject(); JSONObject companyFile = clientComplianceCompanyMapper.findKycFileByClientId(client.getIntValue("client_id")); - fileJson.put("companyFile",companyFile); + fileJson.put("companyFile", companyFile); if (clientFiles != null && clientFiles.size() > 0) { for (String fileKey : fileKeys) { List clientFileUrl = clientFiles.stream() @@ -3925,7 +3988,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid @Override @Transactional - public List uploadKycFilesForWaitComplianceForApp(JSONObject account, String clientMoniker, JSONObject filesInfo,String fileType) { + public List uploadKycFilesForWaitComplianceForApp(JSONObject account, String clientMoniker, JSONObject filesInfo, String fileType) { JSONObject client = getClientInfoByMoniker(clientMoniker); List fileResult = new ArrayList<>(); if (client == null) { @@ -3933,7 +3996,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } int clientId = client.getIntValue("client_id"); try { - updateFilesForWaitAuditWithoutRepeatForApp(account,clientId, fileType, filesInfo.getString("url"),fileResult); + updateFilesForWaitAuditWithoutRepeatForApp(account, clientId, fileType, filesInfo.getString("url"), fileResult); } catch (Exception e) { logger.error("上传KYC文件失败", e); throw new BadRequestException("上传KYC文件失败" + e.getMessage()); @@ -3942,7 +4005,6 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } - @Override @Transactional public void commitAuthFilesToCompliance(String clientMoniker, JSONObject account, String source) { @@ -4521,14 +4583,14 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } client.put("open_status", 4); clientModifySupport.processClientModify(openStatusModify); - saveClientAuditProcess(client.getIntValue("client_id"), open_status_from, 4, "BD完成签字提交compliance审核", manager); + saveClientAuditProcess(client.getIntValue("client_id"), open_status_from, 4, "BD完成签字提交compliance审核", manager,1); if (manager != null) { // sendMessagetoCompliance(client, manager.getString("display_name")); sendCommissionWechatMessage(client); } } - private void saveClientAuditProcess(int client_id, Integer open_status_form, Integer open_status_to, String remark, JSONObject manager) { + private void saveClientAuditProcess(int client_id, Integer open_status_form, Integer open_status_to, String remark, JSONObject manager,int type) { JSONObject log = new JSONObject(); try { log.put("client_id", client_id); @@ -4539,6 +4601,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid log.put("operator_id", StringUtils.isNotEmpty(manager.getString("manager_id")) ? manager.getString("manager_id") : manager.getString("account_id")); log.put("operator", manager.getString("display_name")); log.put("create_time", new Date()); + log.put("type",type); log.put("remark", remark); clientAuditProcessMapper.save(log); } catch (Exception e) { @@ -4554,6 +4617,54 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid throw new InvalidShortIdException(); } client.putAll(clientConfigService.find(client.getIntValue("client_id"))); + + beforeCommitToDoAgreeValid(client, manager); + + OpenStatusModify openStatusModify = new OpenStatusModify(manager, clientMoniker, 1); + openStatusModify.setApprove_result(4); + openStatusModify.setApprove_time(new Date()); + clientModifySupport.processClientModify(openStatusModify); + saveClientAuditProcess(client.getIntValue("client_id"), null, 1, "提交Card Payment Compliance制作合同", manager,1); + if (manager != null) { + // sendAgreeFileMsgtoCompliance(client, manager.getString("display_name")); + sendCommissionWechatMessage(client); + } + } + + @Override + @Transactional + public void commitToDoCardAgreeFile(String clientMoniker, JSONObject manager) { + JSONObject client = getClientInfoByMoniker(clientMoniker); + if (client == null) { + throw new InvalidShortIdException(); + } + int clientId = client.getIntValue("client_id"); + client.putAll(clientConfigService.find(clientId)); + beforeCommitToDoAgreeValid(client, manager); + + JSONObject cardFlowInfo = clientCardFlowMapper.findClient(clientId); + if(null != cardFlowInfo){ + JSONObject cardFlow = new JSONObject(){{ + put("client_id",clientId); + put("approve_result",4); + put("open_status",1); + put("approve_time",new Date()); + }}; + clientCardFlowMapper.update(cardFlow); + }else{ + JSONObject cardFlow = new JSONObject(){{ + put("client_id",clientId); + put("open_status",1); + put("approve_result",4); + put("approve_time",new Date()); + }}; + clientCardFlowMapper.save(cardFlow); + } + + saveClientAuditProcess(client.getIntValue("client_id"), null, 1, "提交Compliance制作合同", manager,2); + } + + private void beforeCommitToDoAgreeValid(JSONObject client, JSONObject manager) { if (manager != null && ManagerRole.BD_USER.hasRole(manager.getIntValue("role"))) { int bdOperatClientRole = clientBDMapper.checkBDPermission(client.getIntValue("client_id"), manager.getString("manager_id")); if (bdOperatClientRole <= 0) { @@ -4570,15 +4681,6 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid if (account == null || account.size() <= 0) { throw new BadRequestException("The Partner's Bank Account is not config!"); } - OpenStatusModify openStatusModify = new OpenStatusModify(manager, clientMoniker, 1); - openStatusModify.setApprove_result(4); - openStatusModify.setApprove_time(new Date()); - clientModifySupport.processClientModify(openStatusModify); - saveClientAuditProcess(client.getIntValue("client_id"), null, 1, "提交Compliance制作合同", manager); - if (manager != null) { - // sendAgreeFileMsgtoCompliance(client, manager.getString("display_name")); - sendCommissionWechatMessage(client); - } } @Override @@ -4610,7 +4712,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid openStatusModify.setApprove_result(4); openStatusModify.setApprove_time(new Date()); clientModifySupport.processClientModify(openStatusModify); - saveClientAuditProcess(client.getIntValue("client_id"), open_status_from, 10, "提交绿色通道申请Compliance审核", manager); + saveClientAuditProcess(client.getIntValue("client_id"), open_status_from, 10, "提交绿色通道申请Compliance审核", manager,1); if (manager != null) { // sendGreenChannelMessagetoCompliance(client, manager.getString("display_name")); sendCommissionWechatMessage(client); @@ -4900,7 +5002,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid if (refuse_remark != null && !refuse_remark.isEmpty()) { auditModify.setRefuse_remark(refuse_remark); } - saveClientAuditProcess(client.getIntValue("client_id"), open_status, client.getInteger("open_status"), "打回," + refuse_remark, manager); + saveClientAuditProcess(client.getIntValue("client_id"), open_status, client.getInteger("open_status"), "打回," + refuse_remark, manager,1); clientModifySupport.processClientModify(auditModify); try { @@ -4925,6 +5027,55 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } } + @Override + public void cardRefusePartner(String clientMoniker, JSONObject manager, String refuse_remark) { + JSONObject client = getClientInfoByMoniker(clientMoniker); + if (client == null) { + throw new InvalidShortIdException(); + } + Integer clientId = client.getInteger("client_id"); + JSONObject cardFlowInfo = clientCardFlowMapper.findClient(clientId); + Integer open_status = null; + if(null != cardFlowInfo){ + open_status = cardFlowInfo.getIntValue("open_status"); + if (open_status == 1) { + cardFlowInfo.put("open_status",null); + } else { + cardFlowInfo.put("open_status",open_status - 1); + } + if ( cardFlowInfo.getIntValue("approve_result") == 4 || client.getIntValue("source") == 4) { + cardFlowInfo.put("approve_result",5); + } + if (refuse_remark != null && !refuse_remark.isEmpty()) { + cardFlowInfo.put("refuse_remark",refuse_remark); + } + }else{ + cardFlowInfo.put("open_status",null); + } + saveClientAuditProcess(client.getIntValue("client_id"), open_status, cardFlowInfo.getIntValue("open_status"), "打回," + refuse_remark, manager,2); + clientCardFlowMapper.update(cardFlowInfo); + + try { + if (client.getIntValue("source") == 4) { + String contact_phone = client.getString("contact_phone"); + if (contact_phone.startsWith("+61")) { + ArrayList param = new ArrayList<>(); + param.add(refuse_remark); + try { + smsSender.getSender().sendWithParam("61", contact_phone.replace("+61", ""), REFUSE_CLIENT_TEMPLID, param, "RoyalPay", "", ""); + } catch (Exception ignore) { + throw new ServerErrorException("Phone number is wrong :" + contact_phone); + } + } + } + if (client.getIntValue("source") == 5) { + gatewayMerchantApply.notifyOrgMerchantStatus(client); + } + } catch (Exception e) { + logger.error("RefusePartnerError=======:" + clientMoniker + "," + e.getMessage()); + } + } + @Override @Cacheable(value = ":all_clients:", key = "''+#clientId") public JSONArray getAllClientIds(int clientId) { @@ -5442,6 +5593,94 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } + private void sendCardCommissionWechatMessage(JSONObject client) { + String bd_user_name = client.getString("bd_user_name"); + String client_moniker = "[" + client.getString("client_moniker") + "]"; + String short_name = client.getString("short_name"); + JSONObject cardFlowInfo = clientCardFlowMapper.findClient(client.getInteger("client_id")); + if(null == cardFlowInfo){ + return; + } + if (cardFlowInfo.getIntValue("open_status") == 1) { + List complianceList = managerMapper.getOnlyCompliance(); + if (complianceList != null && complianceList.size() > 0) { + for (JSONObject compliance : complianceList) { + String wxopenid = compliance.getString("wx_openid"); + try { + MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); + TemplateMessage msg = initSendCommissionTemplate(wxopenid, paymentApi.getTemplateId("commission"), "BD申请制作卡支付合同" + client_moniker, + bd_user_name, "制作卡支付合同申请", "BD申请制作" + short_name + "的卡支付合同"); + paymentApi.sendTemplateMessage(msg); + } catch (WechatException e) { + logger.error("Wechat Message Error,open_status=1" + e.getMessage()); + publisher.publishEvent(new WechatExceptionEvent(this, e, "Audit,open_status=1,openid=" + wxopenid)); + } + } + } + return; + } + if (cardFlowInfo.getIntValue("open_status") == 3) { + List bds = clientBDMapper.listClientBDInfoAvailable(client.getIntValue("client_id"), new Date()); + for (JSONObject bd : bds) { + String wxopenid = bd.getString("wx_openid"); + if (wxopenid != null) { + try { + MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); + TemplateMessage msg = initSendCommissionTemplate(wxopenid, paymentApi.getTemplateId("commission"), client_moniker + "卡支付合同制作完成", + "Compliance", "合规材料", "上传完整合规材料,商户:" + short_name); + paymentApi.sendTemplateMessage(msg); + } catch (WechatException e) { + logger.error("Wechat Message Error,open_status=3" + e.getMessage()); + publisher.publishEvent(new WechatExceptionEvent(this, e, "Audit,open_status=3,openid=" + wxopenid)); + + } + } + + } + return; + } + if (cardFlowInfo.getIntValue("open_status") == 4) { + if (client.getIntValue("source") == 4 && !StringUtils.isNotEmpty(bd_user_name)) { + bd_user_name = "自助开通商户"; + } + List complianceList = managerMapper.getOnlyCompliance(); + if (complianceList != null && complianceList.size() > 0) { + for (JSONObject compliance : complianceList) { + String wxopenid = compliance.getString("wx_openid"); + try { + MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); + TemplateMessage msg = initSendCommissionTemplate(wxopenid, paymentApi.getTemplateId("commission"), client_moniker + "卡支付合规材料已提交", + bd_user_name, "审核材料", "已提交合规材料,等待审核"); + paymentApi.sendTemplateMessage(msg); + } catch (WechatException e) { + logger.error("Wechat Message Error,open_status=1" + e.getMessage()); + publisher.publishEvent(new WechatExceptionEvent(this, e, "Audit,open_status=1,openid=" + wxopenid)); + } catch (Exception e) { + logger.error("Wechat Message Error,open_status=1" + e.getMessage()); + } + } + } + return; + } + if (cardFlowInfo.getIntValue("open_status") == 5) { + List bds = clientBDMapper.listClientBDInfoAvailable(client.getIntValue("client_id"), new Date()); + for (JSONObject bd : bds) { + String wxopenid = bd.getString("wx_openid"); + if (wxopenid != null) { + try { + TemplateMessage msg = initTaskFinishTemplate(wxopenid, client_moniker + "已正式开通", "Card Payment Compliance审核通过", ""); + MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); + paymentApi.sendTemplateMessage(msg); + } catch (WechatException e) { + logger.error("Wechat Message Error,open_status=5" + e.getMessage()); + publisher.publishEvent(new WechatExceptionEvent(this, e, "Audit,open_status=5,openid=" + wxopenid)); + } + } + } + return; + } + } + @Override @Cacheable(value = ":all_sub_merchant_id_applices:", key = "#clientMoniker") public List listSubMerchantIdApplys(JSONObject manager, String clientMoniker) { @@ -6048,7 +6287,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } client.put("open_status", 4); clientModifySupport.processClientModify(openStatusModify); - saveClientAuditProcess(client.getIntValue("client_id"), open_status_from, 4, "自助开通商户提交compliance审核", client_account); + saveClientAuditProcess(client.getIntValue("client_id"), open_status_from, 4, "自助开通商户提交compliance审核", client_account,1); if (params != null) { params.put("display_name", client_account.getString("display_name")); @@ -6648,7 +6887,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } @Override - public JSONObject isLessFiles(JSONObject partner){ + public JSONObject isLessFiles(JSONObject partner) { JSONObject client = clientMapper.findClientByMoniker(partner.getString("client_moniker")); if (client == null) { throw new InvalidShortIdException(); @@ -6656,7 +6895,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid if ((client.getIntValue("approve_result") == 2 || client.getIntValue("open_status") == 10 || client.getIntValue("approve_result") == 1 || client.getIntValue("open_status") == 5)) { boolean lessKycFiles = isPartnerKycfilesComplete(partner.getString("client_moniker")); partner.put("lessKycFiles", lessKycFiles); - partner.put("lessComplianceFiles",signInAccountService.checkAuthFileStatus(partner.getJSONObject("client")).getBoolean("client_less_file")); + partner.put("lessComplianceFiles", signInAccountService.checkAuthFileStatus(partner.getJSONObject("client")).getBoolean("client_less_file")); } partner.put("lessKycFiles", false); partner.put("lessComplianceFiles", false); @@ -6679,14 +6918,14 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid throw new InvalidShortIdException(); } JSONObject KycFilesAuth = clientComplianceCompanyMapper.findKycFileComplete(client.getIntValue("client_id")); - if(KycFilesAuth != null){ + if (KycFilesAuth != null) { lessKycFiles = false; } return lessKycFiles; } @Override - public JSONObject partnerIncrementalServiceInfo(String clientMoniker,String channel){ + public JSONObject partnerIncrementalServiceInfo(String clientMoniker, String channel) { JSONObject client = clientMapper.findClientByMoniker(clientMoniker); if (client == null) { throw new InvalidShortIdException(); @@ -6700,16 +6939,16 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } @Override - public JSONObject getClientIncrementalServiceLoginToken(JSONObject account,String sourceCode){ + public JSONObject getClientIncrementalServiceLoginToken(JSONObject account, String sourceCode) { JSONObject client = clientMapper.findClient(account.getIntValue("client_id")); if (client == null) { throw new InvalidShortIdException(); } JSONObject clientConfig = clientConfigMapper.find(account.getIntValue("client_id")); - if(!clientConfig.getBooleanValue("geek_shop_status")){ + if (!clientConfig.getBooleanValue("geek_shop_status")) { throw new BadRequestException("Merchant service not opened"); } - return retailRSvcService.getGeekSsoTokenInfo(sourceCode,client.getString("client_moniker")); + return retailRSvcService.getGeekSsoTokenInfo(sourceCode, client.getString("client_moniker")); } @Override @@ -6913,18 +7152,18 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } @Override - public void changeExtParams(String clientMoniker,JSONObject manager, JSONObject params){ + public void changeExtParams(String clientMoniker, JSONObject manager, JSONObject params) { JSONObject client = getClientInfoByMoniker(clientMoniker); if (client == null) { throw new InvalidShortIdException(); } JSONObject extParmas = JSONObject.parseObject(client.getString("ext_params")); - if("true".equals(params.getString("value"))||"false".equals(params.getString("value"))){ - extParmas.put(params.getString("key"),params.getBoolean("value")); - }else{ - extParmas.put(params.getString("key"),params.getString("value")); + if ("true".equals(params.getString("value")) || "false".equals(params.getString("value"))) { + extParmas.put(params.getString("key"), params.getBoolean("value")); + } else { + extParmas.put(params.getString("key"), params.getString("value")); } - client.put("ext_params",extParmas.toString()); + client.put("ext_params", extParmas.toString()); clientMapper.update(client); } @@ -6970,7 +7209,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } @Override - public void selectBillCodeVersion(JSONObject manager, String clientMoniker, String version){ + public void selectBillCodeVersion(JSONObject manager, String clientMoniker, String version) { JSONObject client = getClientInfoByMoniker(clientMoniker); if (client == null) { throw new InvalidShortIdException(); @@ -6981,26 +7220,26 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } @Override - public void exportLetterOfferPDF(String clientMoniker,HttpServletResponse response) { + public void exportLetterOfferPDF(String clientMoniker, HttpServletResponse response) { JSONObject info = convertClientLetterOfferInfo(clientMoniker); String pdfPath = this.getClass().getClassLoader().getResource("").getPath() + "/templates/pdf/letter_of_offer.pdf"; - String fileName = clientMoniker+"_Letter_of_Offer.pdf"; - publishExcelCardPDFFile(fileName,pdfPath,info,response); + String fileName = clientMoniker + "_Letter_of_Offer.pdf"; + publishExcelCardPDFFile(fileName, pdfPath, info, response); } - private JSONObject convertClientLetterOfferInfo(String clientMoniker){ + private JSONObject convertClientLetterOfferInfo(String clientMoniker) { JSONObject client = getClientInfoByMoniker(clientMoniker); if (client == null) { throw new InvalidShortIdException(); } //合规状态 - if(client.getIntValue("approve_result")!=1 && client.getIntValue("approve_result")==3){ + if (client.getIntValue("approve_result") != 1 && client.getIntValue("approve_result") == 3) { throw new BadRequestException("The merchant failed the audit!"); } //获取数据源 int clientId = client.getInteger("client_id"); JSONObject clientRate = clientRateMapper.latestChannelCleanDays("rpaypmt_card", clientId); - if(clientRate == null){ + if (clientRate == null) { throw new BadRequestException("rpaypmt_card rate Not configured"); } JSONObject cardRate = clientRate.getJSONObject("ext_rates"); @@ -7008,84 +7247,84 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid //装在数据 JSONObject info = new JSONObject(); - info.put("down_date",convertDateEnglish(new Date()));//下载文件日期 - info.put("bussiness_name",client.getString("business_name")+" ABN");//商圈类型 - info.put("partner_address",client.getString("address"));//商家店铺地址 - info.put("partner_country",client.getString("country"));//国家 - info.put("partner_state",client.getString("state"));//洲 - info.put("partner_bussiness_name",client.getString("business_name"));//商户商用名称 - info.put("clean_days",client.getInteger("clean_days"));//T+规则清算天数 - info.put("partner_industry_mcc",client.getInteger("industry"));//商户行业编码 - info.put("legal_bussiness",client.getString("contact_person")+" AS "+client.getString("business_name") + " ABN "+client.getString("abn"));//拼接规则:法人名 AS 商用名称 ABD 编码 - info.put("annual_rate","0");//年费率 - info.put("cost_per_transaction",clientRate.getString("transaction_fee"));//每次交易成本 - info.put("domestic_fee",cardRate.getString("domestic_rate_value"));//国内服务费 - info.put("international_fee",cardRate.getString("overseas_rate_value"));//国际服务费 - info.put("account_reserve","1000");//账户储备金 + info.put("down_date", convertDateEnglish(new Date()));//下载文件日期 + info.put("bussiness_name", client.getString("business_name") + " ABN");//商圈类型 + info.put("partner_address", client.getString("address"));//商家店铺地址 + info.put("partner_country", client.getString("country"));//国家 + info.put("partner_state", client.getString("state"));//洲 + info.put("partner_bussiness_name", client.getString("business_name"));//商户商用名称 + info.put("clean_days", client.getInteger("clean_days"));//T+规则清算天数 + info.put("partner_industry_mcc", client.getInteger("industry"));//商户行业编码 + info.put("legal_bussiness", client.getString("contact_person") + " AS " + client.getString("business_name") + " ABN " + client.getString("abn"));//拼接规则:法人名 AS 商用名称 ABD 编码 + info.put("annual_rate", "0");//年费率 + info.put("cost_per_transaction", clientRate.getString("transaction_fee"));//每次交易成本 + info.put("domestic_fee", cardRate.getString("domestic_rate_value"));//国内服务费 + info.put("international_fee", cardRate.getString("overseas_rate_value"));//国际服务费 + info.put("account_reserve", "1000");//账户储备金 //银行账号信息 - info.put("account_name",bankAccountInfo.getString("account_name"));// - info.put("bsb",bankAccountInfo.getString("bsb_no")); - info.put("account_no",bankAccountInfo.getString("account_no")); - info.put("card_acceptor_name","xxxxxxxxxxxxx"); + info.put("account_name", bankAccountInfo.getString("account_name"));// + info.put("bsb", bankAccountInfo.getString("bsb_no")); + info.put("account_no", bankAccountInfo.getString("account_no")); + info.put("card_acceptor_name", "xxxxxxxxxxxxx"); return info; } @Override public void exportPromotionalOfferPDF(String clientMoniker, String date, HttpServletResponse response) { - JSONObject info = convertPromotionalOfferInfo(clientMoniker,date); + JSONObject info = convertPromotionalOfferInfo(clientMoniker, date); String pdfPath = this.getClass().getClassLoader().getResource("").getPath() + "/templates/pdf/promotional_offer.pdf"; - String fileName = clientMoniker+"_Promotional_Offer.pdf"; - publishExcelCardPDFFile(fileName,pdfPath,info,response); + String fileName = clientMoniker + "_Promotional_Offer.pdf"; + publishExcelCardPDFFile(fileName, pdfPath, info, response); } - private JSONObject convertPromotionalOfferInfo(String clientMoniker,String date){ + private JSONObject convertPromotionalOfferInfo(String clientMoniker, String date) { JSONObject client = getClientInfoByMoniker(clientMoniker); if (client == null) { throw new InvalidShortIdException(); } //合规状态 - if(client.getIntValue("approve_result")!=1 && client.getIntValue("approve_result")==3){ + if (client.getIntValue("approve_result") != 1 && client.getIntValue("approve_result") == 3) { throw new BadRequestException("The merchant failed the audit!"); } int clientId = client.getInteger("client_id"); JSONObject clientRate = clientRateMapper.latestChannelCleanDays("rpaypmt_card", clientId); - if(clientRate == null){ + if (clientRate == null) { throw new BadRequestException("rpaypmt_card rate Not configured"); } JSONObject cardRate = clientRate.getJSONObject("ext_rates"); JSONObject bankAccountInfo = clientBankAccountMapper.clientBankAccounts(clientId).get(0); JSONObject info = new JSONObject(); - info.put("down_date",convertDateEnglish(new Date()));//下载文件日期 - info.put("bussiness_name",client.getString("business_name")+" ABN");//商圈类型 - info.put("partner_address",client.getString("address"));//商家店铺地址 - info.put("partner_country",client.getString("country"));//国家 - info.put("partner_state",client.getString("state"));//洲 - info.put("partner_bussiness_name",client.getString("business_name"));//商户商用名称 - info.put("letter_offer_sub_time",date); - info.put("legal_bussiness",client.getString("contact_person")+" AS "+client.getString("business_name") + " ABN "+client.getString("abn"));//拼接规则:法人名 AS 商用名称 ABD 编码 - info.put("domestic_fee",cardRate.getString("domestic_rate_value"));//国内服务费 - info.put("international_fee",cardRate.getString("overseas_rate_value"));//国际服务费 - info.put("promotional_effective_date","xxxxxxxxx"); - info.put("promotional_period","xxxxxxxxx"); + info.put("down_date", convertDateEnglish(new Date()));//下载文件日期 + info.put("bussiness_name", client.getString("business_name") + " ABN");//商圈类型 + info.put("partner_address", client.getString("address"));//商家店铺地址 + info.put("partner_country", client.getString("country"));//国家 + info.put("partner_state", client.getString("state"));//洲 + info.put("partner_bussiness_name", client.getString("business_name"));//商户商用名称 + info.put("letter_offer_sub_time", date); + info.put("legal_bussiness", client.getString("contact_person") + " AS " + client.getString("business_name") + " ABN " + client.getString("abn"));//拼接规则:法人名 AS 商用名称 ABD 编码 + info.put("domestic_fee", cardRate.getString("domestic_rate_value"));//国内服务费 + info.put("international_fee", cardRate.getString("overseas_rate_value"));//国际服务费 + info.put("promotional_effective_date", "xxxxxxxxx"); + info.put("promotional_period", "xxxxxxxxx"); return info; } @Override - public void exportTermsConditionsPDF(String clientMoniker,HttpServletResponse response) { + public void exportTermsConditionsPDF(String clientMoniker, HttpServletResponse response) { JSONObject client = getClientInfoByMoniker(clientMoniker); if (client == null) { throw new InvalidShortIdException(); } - if(client.getIntValue("approve_result")!=1 && client.getIntValue("approve_result")==3){ + if (client.getIntValue("approve_result") != 1 && client.getIntValue("approve_result") == 3) { throw new BadRequestException("The merchant failed the audit!"); } String pdfPath = this.getClass().getClassLoader().getResource("").getPath() + "/templates/pdf/terms_and_conditions.pdf"; - String fileName = clientMoniker+"_Terms_And_Conditions.pdf"; - publishExcelCardPDFFile(fileName,pdfPath,new JSONObject(),response); + String fileName = clientMoniker + "_Terms_And_Conditions.pdf"; + publishExcelCardPDFFile(fileName, pdfPath, new JSONObject(), response); } - private void publishExcelCardPDFFile (String fileName,String pdfPath,JSONObject info,HttpServletResponse response){ + private void publishExcelCardPDFFile(String fileName, String pdfPath, JSONObject info, HttpServletResponse response) { response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ".pdf"); try { @@ -7105,14 +7344,14 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } } - private String convertDateEnglish(Date date){ - String[] months= {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Spt","Oct","Nov","Dec"}; + private String convertDateEnglish(Date date) { + String[] months = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Spt", "Oct", "Nov", "Dec"}; Calendar calendar = Calendar.getInstance(); calendar.setTime(date); int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH); int day = calendar.get(Calendar.DAY_OF_MONTH); - return day+" "+ months[month]+" "+ year; + return day + " " + months[month] + " " + year; } public void saveLegalAndMarketingInfo(JSONObject partner) { diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java b/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java index 6da1c017c..8fc8d8cce 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java @@ -280,6 +280,11 @@ public class PartnerManageController { clientManager.auditClient(manager, clientMoniker, pass.getIntValue("pass")); } + @ManagerMapping(value = "/{clientMoniker}/card_audit", method = RequestMethod.PUT, role = ManagerRole.OPERATOR) + public void auditCardPartner(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String clientMoniker, @RequestBody JSONObject pass) { + clientManager.auditCardClient(manager, clientMoniker, pass.getIntValue("pass")); + } + @ManagerMapping(value = "/{clientMoniker}/aduit/green_channel", method = RequestMethod.PUT, role = ManagerRole.OPERATOR) public void auditPartnerGreenChannel(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String clientMoniker) { clientManager.auditClientGreenChannel(manager, clientMoniker); @@ -300,6 +305,11 @@ public class PartnerManageController { clientManager.refusePartner(clientMoniker, manager, refuse.getString("refuse_remark")); } + @ManagerMapping(value = "/{clientMoniker}/card_audit/refuse", method = RequestMethod.PUT, role = ManagerRole.OPERATOR) + public void cardRefusePartner(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @RequestBody JSONObject refuse) { + clientManager.cardRefusePartner(clientMoniker, manager, refuse.getString("refuse_remark")); + } + @ManagerMapping(value = "/{clientMoniker}/common_sub_merchant_id", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR}) public void switchCommonSubMerchantId(@PathVariable String clientMoniker, @RequestBody JSONObject pass, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { clientManager.switchPermission(manager, clientMoniker, "common_sub_merchant_id", pass.getBooleanValue("allow")); @@ -629,6 +639,17 @@ public class PartnerManageController { clientManager.commitToDoAgreeFile(clientMoniker, manager); } + //TODO BD提交申请卡合规 + /** + * 提交资料,申请卡支付 + * @param clientMoniker + * @param manager + */ + @ManagerMapping(value = "/{clientMoniker}/make_card_agree_file", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.BD_USER}) + public void commitToDoCardAgreeFile(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + clientManager.commitToDoCardAgreeFile(clientMoniker, manager); + } + @ManagerMapping(value = "/{clientMoniker}/compliance/green_channel", method = RequestMethod.PUT, role = {ManagerRole.ADMIN, ManagerRole.BD_USER}) public void commitToGreenChannel(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { clientManager.commitToGreenChannel(clientMoniker, manager); diff --git a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientMapper.xml index 79ccd5e88..086d71004 100644 --- a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientMapper.xml +++ b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientMapper.xml @@ -133,6 +133,24 @@ c.open_status=1 or c.open_status=2 or c.open_status=4) + + OR (c.client_id NOT IN ( + SELECT client_id FROM sys_clients_card_flow + ) + OR c.client_id IN ( + SELECT client_id FROM sys_clients_card_flow AS cardFlow + WHERE cardFlow.approve_result = 4 or approve_result = 1 + )) + + + AND (c.client_id NOT IN ( + SELECT client_id FROM sys_clients_card_flow + ) + OR c.client_id IN ( + SELECT client_id FROM sys_clients_card_flow AS cardFlow + WHERE cardFlow.approve_result = 4 or approve_result = 1 + )) + and c.source=4 diff --git a/src/main/ui/static/payment/partner/partner-manage.js b/src/main/ui/static/payment/partner/partner-manage.js index 6f74bc965..20874bac1 100644 --- a/src/main/ui/static/payment/partner/partner-manage.js +++ b/src/main/ui/static/payment/partner/partner-manage.js @@ -533,6 +533,72 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter }) }); }; + $scope.passCardClient = function () { + if (!$rootScope.complianceCheck) { + alert("please check first"); + return; + } + if (!$rootScope.complianceCheck.authFile) { + alert("Compliance Files not checked"); + return; + } + if (!$rootScope.complianceCheck.clientInfo) { + alert("Partner Detail not checked"); + return; + } + if (!$rootScope.complianceCheck.bankAccount) { + alert("Bank Account not checked"); + return; + } + var title = 'Audit Partner Card'; + var content = 'Are you sure to mark partner ' + $scope.partner.company_name + ' audited?'; + var choises = ''; + var contentHtml = ''; + if ($scope.isComplianceOfCompanyName || $scope.isComplianceOfShortName + || $scope.isComplianceOfBusinessStructure) { + var info = []; + if ($scope.isComplianceOfCompanyName) { + info.push('Company Name'); + } + if ($scope.isComplianceOfShortName) { + info.push('Short Name'); + } + if ($scope.isComplianceOfBusinessStructure) { + info.push('Business Structure'); + } + title = 'Warning'; + contentHtml = $sce.trustAsHtml('本次提交的商户[' + $scope.partner.company_name + '],' + info.toString() + '存在微信渠道不合规信息'); + choises = [{label: '取消', className: 'btn-danger', key: '2', dismiss: true}, + {label: '确认提交', className: 'btn-success', key: '1'}]; + content = ''; + } + commonDialog.confirm({ + title: title, + content: content, + choises: choises, + contentHtml: contentHtml + }).then(function () { + $http.put('/sys/partners/' + $scope.partner.client_moniker + '/card_audit', {pass: 1}).then(function () { + if ($scope.partner.approve_result == 2 && ($scope.partner.source == 1 || $scope.partner.source == 2)) { + commonDialog.alert({ + title: 'Success', + content: 'Comply Passed!', + type: 'success' + }); + } else { + commonDialog.alert({ + title: 'Success', + content: 'Comply Passed! Email will send to contact email address soon.', + type: 'success' + }); + } + delete $rootScope.complianceCheck; + $state.reload(); + }, function (resp) { + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); + }) + }); + }; $scope.pass2GreenChannel = function () { commonDialog.confirm({ title: 'Green Channel Audit Partner', @@ -648,6 +714,21 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter }) }; + $scope.cardRefuse = function(){ + commonDialog.inputText({title: 'refuse cause'}).then(function (text) { + $http.put('/sys/partners/' + $scope.partner.client_moniker + '/card_audit/refuse', {refuse_remark: text}).then(function () { + commonDialog.alert({ + title: 'Success', + content: 'Card Audit application has been refused.', + type: 'success' + }); + $state.reload(); + }, function (resp) { + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); + }) + }) + } + $scope.deleteClient = function () { commonDialog.confirm({ title: 'Delete Partner', @@ -712,6 +793,20 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter ); }; + $scope.apply2makeCardAgreeFile = function () { + $http.get('/sys/partners/' + $scope.partner.client_moniker + '/make_card_agree_file').then(function () { + commonDialog.alert({ + title: 'Success!', + content: '已提交制作合同!', + type: 'success' + }); + $state.reload(); + }, function (resp) { + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); + } + ); + }; + $scope.commit2GreenChannel = function () { commonDialog.confirm({ title: 'Audit Partner', diff --git a/src/main/ui/static/payment/partner/templates/partner_detail.html b/src/main/ui/static/payment/partner/templates/partner_detail.html index 5514efada..f36ca7470 100644 --- a/src/main/ui/static/payment/partner/templates/partner_detail.html +++ b/src/main/ui/static/payment/partner/templates/partner_detail.html @@ -58,11 +58,11 @@
  • Partner Detail
  • -
    +
    -

    Compliance Compliance (Refused :{{partner.refuse_remark}}) @@ -95,6 +95,8 @@
    -
    下载合同 - + Notify BD @@ -155,14 +157,12 @@

    - -
    -

    Operation +

    + + RP Operation (Refused :{{partner.refuse_remark}} )

    + + + +
    +
    +

    + Compliance (Refused + :{{partner.refuse_remark}}) + (The Partner Using Green Channel Now!) + 【目前状态】- + + (自助申请)资料完善中 + (自助申请)已开通 + (自助申请)快速开通等待提交合规材料 + (自助申请)待审核(材料已提交) + + + 资料完善中 + 待审核(合同制作中) + 合同制作完成 + BD处理中 + 待审核(合规文件已提交) + 通过 + 不通过 + + (已禁用) +

    + +
    +
    +
    + + + + 制作全支付合同 + + 上传合同 (通用合同请选择制作合同,非通用合同模板请人工制作合同后上传) +
    +
    + + +
    + 下载合同 + + + Notify BD + +
    +
    +
    + +
    + +
    +
    + + +
    + + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Card Payment Operation + (Refused + :{{partner.card_flow_info.refuse_remark}} + )(The Partner Using Green Channel Now!) + 【目前状态】- + 资料完善中 + 待审核(合同制作中) + 合同制作完成 + BD处理中 + 待审核(合规文件已提交) + 通过 + 不通过 + 绿色通道申请中 +

    +
    +
    + + 下载合同 +
    + +
    +
    + +
    +
    +
    +
    + +
    + +
    +
    + + +
    + + +
    +
    +
    +
    +
    +
    + +
    +
    +

    Solved

    +
    +
    +
    Make sure you have send the email to client.
    +
    + +
    +
    +
    + +
    diff --git a/src/main/ui/static/payment/partner/templates/partners.html b/src/main/ui/static/payment/partner/templates/partners.html index 34b0bfea2..c6ca05969 100644 --- a/src/main/ui/static/payment/partner/templates/partners.html +++ b/src/main/ui/static/payment/partner/templates/partners.html @@ -370,6 +370,16 @@ + + + + @@ -476,19 +486,37 @@ - - 通过({{partner.approve_time}}) - 资料完善中 - (自助开通)资料完善中 - 自助开通试用中({{partner.approve_time}}~{{partner.expiry_time}}) - 不通过({{partner.approve_time}}) - 申请打回({{partner.refuse_remark|limitTo:15}}) - 等待合规 - 自助开通(等待合规) - 合同制作完成 - 等待BD上传材料审核 - 绿色通道申请中 - 等待合规 + +
    + + 通过({{partner.approve_time}}) + 资料完善中 + (自助开通)资料完善中 + 自助开通试用中({{partner.approve_time}}~{{partner.expiry_time}}) + 不通过({{partner.approve_time}}) + 申请打回({{partner.refuse_remark|limitTo:15}}) + 等待合规 + 自助开通(等待合规) + 合同制作完成 + 等待BD上传材料审核 + 绿色通道申请中 + 等待合规 +
    +
    + 等待BD上传材料审核 +
    +
    + + 通过({{partner.card_approve_flow_info.approve_time}}) + 资料完善中 + (自助开通)资料完善中 + 不通过({{partner.card_approve_flow_info.approve_time}}) + 申请打回({{partner.card_approve_flow_info.refuse_remark|limitTo:15}}) + 等待合规 + 合同制作完成 + 等待BD上传材料审核 + 等待合规 +
    From 982f24c64a09714f38cf6a91e6e7e71a55188cc2 Mon Sep 17 00:00:00 2001 From: luoyang Date: Mon, 27 Apr 2020 18:06:55 +0800 Subject: [PATCH 09/40] =?UTF-8?q?add=20mw=E5=90=88=E8=A7=84=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E3=80=81=E8=B4=A2=E5=8A=A1=E6=8A=A5=E8=A1=A8=E7=9B=B8?= =?UTF-8?q?=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mappers/system/ClientMWFilesMapper.java | 3 +- .../beans/ClientMWAuthFilesInfo.java | 99 ++++-- .../core/impls/ClientManagerImpl.java | 26 +- .../merchants/enums/UPayAuthFileEnum.java | 26 +- .../manage/tradelog/core/TradeLogService.java | 2 + .../core/impls/TradeLogServiceImpl.java | 116 ++++++- .../tradelog/web/TradeFlowController.java | 6 + .../mappers/payment/TransactionMapper.xml | 4 +- .../jasper/partner_upay_invoice_gst.jasper | Bin 0 -> 83133 bytes src/main/ui/static/analysis/clearing-log.js | 4 + .../templates/settlement_transactions.html | 10 + .../commons/services/clearingDetailService.js | 4 + src/main/ui/static/config/bdprize/bdprize.js | 4 + .../static/payment/partner/partner-manage.js | 324 +++++++++++++----- .../partner/templates/add_partner.html | 2 +- .../partner/templates/partner_auth_files.html | 29 +- .../templates/partner_cp_auth_files.html | 2 +- .../partner/templates/partner_detail.html | 52 ++- .../partner/templates/partner_edit.html | 2 +- .../templates/partner_mw_auth_files.html | 221 +++++++----- .../partner/templates/partner_settlement.html | 7 +- .../tradelog/templates/balance_report.html | 3 +- .../templates/partner_settlement_dialog.html | 11 + .../templates/partner_settlement_logs.html | 5 + .../ui/static/payment/tradelog/transflow.js | 3 + 25 files changed, 728 insertions(+), 237 deletions(-) create mode 100644 src/main/resources/jasper/partner_upay_invoice_gst.jasper diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientMWFilesMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientMWFilesMapper.java index 88efbe614..e5064a1cf 100644 --- a/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientMWFilesMapper.java +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientMWFilesMapper.java @@ -1,6 +1,7 @@ package au.com.royalpay.payment.manage.mappers.system; import com.alibaba.fastjson.JSONObject; +import com.github.miemiedev.mybatis.paginator.domain.PageBounds; import com.yixsoft.support.mybatis.autosql.annotations.AdvanceSelect; import com.yixsoft.support.mybatis.autosql.annotations.AutoMapper; import com.yixsoft.support.mybatis.autosql.annotations.AutoSql; @@ -22,5 +23,5 @@ public interface ClientMWFilesMapper { @AutoSql(SqlType.SELECT) @AdvanceSelect(addonWhereClause = "is_valid = 1") - List findClientFile(@Param("client_id") int clientId); + List findClientFile(@Param("client_id") int clientId, PageBounds pageBounds); } diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientMWAuthFilesInfo.java b/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientMWAuthFilesInfo.java index 51d263c92..45235245c 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientMWAuthFilesInfo.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientMWAuthFilesInfo.java @@ -7,11 +7,16 @@ import org.apache.commons.lang3.StringUtils; * Created by yishuqian on 07/03/2017. */ public class ClientMWAuthFilesInfo { - private String upay_application_form; - private String upay_agreement_file; + private String client_bank_file; + private String client_company_file; + private String refund_exchange_policy; + private String upay_privacy_policy; + private String card_security_policy; + private String upay_promotional_offer; + private String upay_terms_conditions; private String upay_offer_letter; private String upay_driver_license; - private String upay_residence_certificate; + private String kyc_utility_bill_file; private String upay_risk_level; private String upay_risk_remark; @@ -30,14 +35,6 @@ public class ClientMWAuthFilesInfo { return params; } - public String getUpay_agreement_file() { - return upay_agreement_file; - } - - public String getUpay_application_form() { - return upay_application_form; - } - public String getUpay_driver_license() { return upay_driver_license; } @@ -46,18 +43,6 @@ public class ClientMWAuthFilesInfo { return upay_offer_letter; } - public void setUpay_agreement_file(String upay_agreement_file) { - this.upay_agreement_file = upay_agreement_file; - } - - public void setUpay_application_form(String upay_application_form) { - this.upay_application_form = upay_application_form; - } - - public String getUpay_residence_certificate() { - return upay_residence_certificate; - } - public String getUpay_risk_level() { return upay_risk_level; } @@ -70,10 +55,6 @@ public class ClientMWAuthFilesInfo { this.upay_offer_letter = upay_offer_letter; } - public void setUpay_residence_certificate(String upay_residence_certificate) { - this.upay_residence_certificate = upay_residence_certificate; - } - public String getUpay_risk_remark() { return upay_risk_remark; } @@ -85,4 +66,68 @@ public class ClientMWAuthFilesInfo { public void setUpay_risk_remark(String upay_risk_remark) { this.upay_risk_remark = upay_risk_remark; } + + public String getCard_security_policy() { + return card_security_policy; + } + + public String getClient_bank_file() { + return client_bank_file; + } + + public String getClient_company_file() { + return client_company_file; + } + + public String getUpay_privacy_policy() { + return upay_privacy_policy; + } + + public String getUpay_promotional_offer() { + return upay_promotional_offer; + } + + public void setCard_security_policy(String card_security_policy) { + this.card_security_policy = card_security_policy; + } + + public String getUpay_terms_conditions() { + return upay_terms_conditions; + } + + public void setClient_bank_file(String client_bank_file) { + this.client_bank_file = client_bank_file; + } + + public void setClient_company_file(String client_company_file) { + this.client_company_file = client_company_file; + } + + public void setUpay_privacy_policy(String upay_privacy_policy) { + this.upay_privacy_policy = upay_privacy_policy; + } + + public void setUpay_promotional_offer(String upay_promotional_offer) { + this.upay_promotional_offer = upay_promotional_offer; + } + + public void setUpay_terms_conditions(String upay_terms_conditions) { + this.upay_terms_conditions = upay_terms_conditions; + } + + public String getRefund_exchange_policy() { + return refund_exchange_policy; + } + + public void setRefund_exchange_policy(String refund_exchange_policy) { + this.refund_exchange_policy = refund_exchange_policy; + } + + public String getKyc_utility_bill_file() { + return kyc_utility_bill_file; + } + + public void setKyc_utility_bill_file(String kyc_utility_bill_file) { + this.kyc_utility_bill_file = kyc_utility_bill_file; + } } diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index 3295258dc..56088735f 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -438,7 +438,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } client.putAll(clientConfig); JSONObject upayInfo = sysClientUpayProfileMapper.findInfo(client.getIntValue("client_id")); - if(null != upayInfo){ + if (upayInfo != null) { client.putAll(upayInfo); } client.put("unsubscribe", mailUnsubMapper.findOneByClientMoniker(clientMoniker) == null ? false : true); @@ -3435,7 +3435,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid if (client == null) { throw new InvalidShortIdException(); } - List files = clientMWAuthFilesInfo.findClientFile(client.getIntValue("client_id")); + List files = clientMWAuthFilesInfo.findClientFile(client.getIntValue("client_id"), new PageBounds(1, 999999, Order.formString("last_update_date.asc"))); if (files != null && files.size() > 0) { List filePaths = new ArrayList<>(); for (JSONObject file : files) { @@ -3641,7 +3641,12 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } int clientId = client.getIntValue("client_id"); params.put("client_id", client.getIntValue("client_id")); - clientConfigMapper.update(params); + JSONObject upayInfo = sysClientUpayProfileMapper.findInfo(clientId); + if (upayInfo == null) { + sysClientUpayProfileMapper.save(params); + }else { + sysClientUpayProfileMapper.update(params); + } } @Override @@ -3759,7 +3764,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid if (client == null) { throw new InvalidShortIdException(); } - List clientFiles = clientMWAuthFilesInfo.findClientFile(client.getIntValue("client_id")); + List clientFiles = clientMWAuthFilesInfo.findClientFile(client.getIntValue("client_id"), new PageBounds(1,999999, Order.formString("last_update_date.asc"))); JSONObject fileJson = new JSONObject(); for (JSONObject file : clientFiles) { fileJson.put(file.getString("file_name"), file.getString("file_value")); @@ -3917,11 +3922,16 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } int clientId = client.getIntValue("client_id"); try { - updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.UPAY_APPLICATION_FORM.getFileName(), filesInfo.getUpay_application_form()); - updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.UPAY_AGREEMENT_FILE.getFileName(), filesInfo.getUpay_agreement_file()); - updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.UPAY_OFFER_LETTER.getFileName(), filesInfo.getUpay_offer_letter()); + updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.CLIENT_BANK_FILE.getFileName(), filesInfo.getClient_bank_file()); + updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.CLIENT_COMPANY_FILE.getFileName(), filesInfo.getClient_company_file()); updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.UPAY_DRIVER_LICENSE.getFileName(), filesInfo.getUpay_driver_license()); - updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.UPAY_RESIDENCE_CERTIFICATE.getFileName(), filesInfo.getUpay_residence_certificate()); + updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.REFUND_EXCHANGE_POLICY.getFileName(), filesInfo.getRefund_exchange_policy()); + updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.UPAY_PRIVACY_POLICY.getFileName(), filesInfo.getUpay_privacy_policy()); + updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.CARD_SECURITY_POLICY.getFileName(), filesInfo.getCard_security_policy()); + updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.UPAY_OFFER_LETTER.getFileName(), filesInfo.getUpay_offer_letter()); + updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.UPAY_PROMOTIONAL_OFFER.getFileName(), filesInfo.getUpay_promotional_offer()); + updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.UPAY_TERMS_CONDITIONS.getFileName(), filesInfo.getUpay_terms_conditions()); + updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.KYC_UTILITY_BILL_FILE.getFileName(), filesInfo.getKyc_utility_bill_file()); } catch (Exception e) { logger.error("上传合规文件失败", e); } diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/enums/UPayAuthFileEnum.java b/src/main/java/au/com/royalpay/payment/manage/merchants/enums/UPayAuthFileEnum.java index 4118df321..992e1280c 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/enums/UPayAuthFileEnum.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/enums/UPayAuthFileEnum.java @@ -2,11 +2,16 @@ package au.com.royalpay.payment.manage.merchants.enums; public enum UPayAuthFileEnum { ALL(""), - UPAY_APPLICATION_FORM("upay_application_form"), - UPAY_AGREEMENT_FILE("upay_agreement_file"), - UPAY_OFFER_LETTER("upay_offer_letter"), + CLIENT_BANK_FILE("client_bank_file"), + CLIENT_COMPANY_FILE("client_company_file"), UPAY_DRIVER_LICENSE("upay_driver_license"), - UPAY_RESIDENCE_CERTIFICATE("upay_residence_certificate"); + REFUND_EXCHANGE_POLICY("refund_exchange_policy"), + UPAY_PRIVACY_POLICY("upay_privacy_policy"), + CARD_SECURITY_POLICY("card_security_policy"), + UPAY_OFFER_LETTER("upay_offer_letter"), + UPAY_PROMOTIONAL_OFFER("upay_promotional_offer"), + UPAY_TERMS_CONDITIONS("upay_terms_conditions"), + KYC_UTILITY_BILL_FILE("kyc_utility_bill_file"); private final String fileName; @@ -19,10 +24,15 @@ public enum UPayAuthFileEnum { } public String[] getFileNameArrays() { - return new String[]{UPAY_APPLICATION_FORM.getFileName(), - UPAY_AGREEMENT_FILE.getFileName(), + return new String[]{CLIENT_BANK_FILE.getFileName(), + CLIENT_COMPANY_FILE.getFileName(), + UPAY_OFFER_LETTER.getFileName(), + REFUND_EXCHANGE_POLICY.getFileName(), + UPAY_PRIVACY_POLICY.getFileName(), + CARD_SECURITY_POLICY.getFileName(), UPAY_OFFER_LETTER.getFileName(), - UPAY_DRIVER_LICENSE.getFileName(), - UPAY_RESIDENCE_CERTIFICATE.getFileName()}; + UPAY_PROMOTIONAL_OFFER.getFileName(), + UPAY_TERMS_CONDITIONS.getFileName(), + KYC_UTILITY_BILL_FILE.getFileName()}; } } diff --git a/src/main/java/au/com/royalpay/payment/manage/tradelog/core/TradeLogService.java b/src/main/java/au/com/royalpay/payment/manage/tradelog/core/TradeLogService.java index b7627151d..a9e3a978a 100644 --- a/src/main/java/au/com/royalpay/payment/manage/tradelog/core/TradeLogService.java +++ b/src/main/java/au/com/royalpay/payment/manage/tradelog/core/TradeLogService.java @@ -36,6 +36,8 @@ public interface TradeLogService { void exportTransFlow(TradeLogQuery query, JSONObject partner, HttpServletResponse response) throws Exception; + void exportUpayTransFlow(TradeLogQuery query, JSONObject partner, HttpServletResponse response) throws Exception; + void exportTransFlowApi(TradeLogQuery query, JSONObject partner, HttpServletResponse response) throws Exception; void exportExcel(TradeLogQuery query, JSONObject partner, HttpServletResponse response) throws Exception; diff --git a/src/main/java/au/com/royalpay/payment/manage/tradelog/core/impls/TradeLogServiceImpl.java b/src/main/java/au/com/royalpay/payment/manage/tradelog/core/impls/TradeLogServiceImpl.java index 8d06b70dc..b6046766c 100644 --- a/src/main/java/au/com/royalpay/payment/manage/tradelog/core/impls/TradeLogServiceImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/tradelog/core/impls/TradeLogServiceImpl.java @@ -136,6 +136,8 @@ public class TradeLogServiceImpl implements TradeLogService { private org.springframework.core.io.Resource trans_flow; @Value("classpath:/jasper/incremental_partner_invoice_gst.jasper") private org.springframework.core.io.Resource incremental_trans_flow; + @Value("classpath:/jasper/partner_upay_invoice_gst.jasper") + private org.springframework.core.io.Resource upay_trans_flow; @Value("classpath:/jasper/royalpay_logo.png") private org.springframework.core.io.Resource logo; @Value("classpath:/jasper/trans_excel.jasper") @@ -573,6 +575,30 @@ public class TradeLogServiceImpl implements TradeLogService { return result; } + private JSONObject listPartnerTransFlowByExportPdf(TradeLogQuery query, JSONObject partner, String[] channels) throws Exception { + int clientId = partner.getIntValue("client_id"); + String timezone = partner.getJSONObject("client").getString("timezone"); + JSONObject params = query.toParams(timezone); + params.put("channel", channels); + clientManager.validateClients(clientId, params); + params.put("client_id", clientId); + clientManager.queryModifyClientIds(clientId, params); + List logs = transactionMapper.listTransFlow(params); + TimeZoneUtils.switchTimeZoneToString(logs, timezone, "dd/MM/yyyy HH:mm:ss", Collections.singletonList("transaction_time")); + TimeZoneUtils.switchTimeZoneToString(logs, timezone, "dd/MM/yyyy", Collections.singletonList("clearing_time")); + + final JSONObject analysis = analysisTransLogs(logs); + + JSONObject result = new JSONObject(); + result.put("data", logs); + analysis.put("balance", transactionMapper.analysisBalance(params)); + if (analysis.containsKey("paid_fee") && analysis.containsKey("refund_fee")) { + analysis.put("actual_fee", analysis.getBigDecimal("paid_fee").add(analysis.getBigDecimal("refund_fee"))); + } + result.put("analysis", analysis); + return result; + } + private JSONObject analysisTransLogs(List logs) { final JSONObject analysis = new JSONObject(); analysis.put("order_count", logs.size()); @@ -633,10 +659,18 @@ public class TradeLogServiceImpl implements TradeLogService { .filter(log -> log.getBigDecimal("settle_amount") != null) .map(log -> getSymbol(log).multiply(log.getBigDecimal("incremental_surcharge"))) .reduce(BigDecimal::add).orElse(BigDecimal.ZERO)); + analysis.put("total_transaction_fee", logs.parallelStream() + .filter(log -> log.getBigDecimal("settle_amount") != null) + .map(log -> getSymbol(log).multiply(log.getBigDecimal("transaction_fee"))) + .reduce(BigDecimal::add).orElse(BigDecimal.ZERO)); analysis.put("total_incremental_tax", logs.parallelStream() .filter(log -> log.getBigDecimal("settle_amount") != null) .map(log -> getSymbol(log).multiply(log.getBigDecimal("incremental_surcharge").divide(new BigDecimal(10), 2, RoundingMode.HALF_UP))) .reduce(BigDecimal::add).orElse(BigDecimal.ZERO)); + analysis.put("total_transaction_fee_tax", logs.parallelStream() + .filter(log -> log.getBigDecimal("settle_amount") != null) + .map(log -> getSymbol(log).multiply(log.getBigDecimal("transaction_fee").divide(new BigDecimal(10), 2, RoundingMode.HALF_UP))) + .reduce(BigDecimal::add).orElse(BigDecimal.ZERO)); analysis.put("total_surcharge", logs.parallelStream() .filter(log -> log.getBigDecimal("settle_amount") != null) .map(log -> getSymbol(log).multiply(log.getBigDecimal("total_surcharge").add(log.getBigDecimal("tax_amount")))) @@ -679,7 +713,7 @@ public class TradeLogServiceImpl implements TradeLogService { @Override public void exportTransFlow(TradeLogQuery query, JSONObject partner, HttpServletResponse response) throws Exception { - JSONObject transFlow = listPartnerTransFlow(query, partner); + JSONObject transFlow = listPartnerTransFlowByExportPdf(query, partner,new String[]{"Wechat","Alipay","AlipayOnline"}); JSONObject analysis = transFlow.getJSONObject("analysis"); JSONObject client = clientManager.getClientInfo(partner.getIntValue("client_id")); if (!transFlow.getJSONArray("data").isEmpty()) { @@ -736,7 +770,7 @@ public class TradeLogServiceImpl implements TradeLogService { }); JRDataSource jrDataSource = new JRBeanCollectionDataSource(dataList); response.setContentType("application/pdf"); - String fileName = client.getString("client_moniker") + "_" + parmerters.getString("dateRange").replaceAll("/", ""); + String fileName = client.getString("client_moniker") + "_Cross_Border_" + parmerters.getString("dateRange").replaceAll("/", ""); response.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ".pdf"); OutputStream outs = response.getOutputStream(); JSONObject clientIncrement = clientIncrementalMapper.findByClinetIdAndChannel(client.getIntValue("client_id"), "RP跨境商城"); @@ -752,6 +786,84 @@ public class TradeLogServiceImpl implements TradeLogService { } } + @Override + public void exportUpayTransFlow(TradeLogQuery query, JSONObject partner, HttpServletResponse response) throws Exception { + JSONObject transFlow = listPartnerTransFlowByExportPdf(query, partner,new String[]{"rpaypmt_card","rpaypmt_dd"}); + JSONObject analysis = transFlow.getJSONObject("analysis"); + JSONObject client = clientManager.getClientInfo(partner.getIntValue("client_id")); + if (!transFlow.getJSONArray("data").isEmpty()) { + try { + List dataList = transFlow.getJSONArray("data").toJavaList(JSONObject.class); + JSONObject parmerters = new JSONObject(); + parmerters.put("dateFrom", StringUtils.isNotBlank(query.getDatefrom()) + ? DateFormatUtils.format(DateUtils.parseDate(query.getDatefrom(), "yyyyMMdd"), "dd/MM/yyyy") : ""); + parmerters.put("dateTo", + StringUtils.isNotBlank(query.getDateto()) + ? DateFormatUtils.format(DateUtils.parseDate(query.getDateto(), "yyyyMMdd"), "dd/MM/yyyy") + : DateFormatUtils.format(new Date(), "dd/MM/yyyy")); + parmerters.put("dateRange", (StringUtils.isNotBlank(parmerters.getString("dateFrom")) ? parmerters.getString("dateFrom") : "") + "~" + + parmerters.getString("dateTo")); + parmerters.put("partnerCode", client.getString("client_moniker")); + parmerters.put("clientName", client.getString("company_name")); + parmerters.put("clientAddress", client.getString("address")); + parmerters.put("balance", analysis.getDoubleValue("balance")); + parmerters.put("logo", logo.getInputStream()); + parmerters.put("actual_fee", takeDecimalOrDefault(analysis, "actual_fee", BigDecimal.ZERO)); + parmerters.put("totalSettledAmount", takeDecimalOrDefault(analysis, "total_settle_amount", BigDecimal.ZERO)); + parmerters.put("royalpay_charge", takeDecimalOrDefault(analysis, "total_royal_surcharge", BigDecimal.ZERO)); + parmerters.put("total_fee", takeDecimalOrDefault(analysis, "total_surcharge", BigDecimal.ZERO)); + parmerters.put("alipay_fee", takeDecimalOrDefault(analysis, "alipay_fee", BigDecimal.ZERO)); + parmerters.put("wechat_fee", takeDecimalOrDefault(analysis, "wechat_fee", BigDecimal.ZERO)); + parmerters.put("bestpay_fee", takeDecimalOrDefault(analysis, "bestpay_fee", BigDecimal.ZERO)); + parmerters.put("jd_fee", takeDecimalOrDefault(analysis, "jd_fee", BigDecimal.ZERO)); + parmerters.put("alipay_online_fee", takeDecimalOrDefault(analysis, "alipay_online_fee", BigDecimal.ZERO)); + parmerters.put("gst", takeDecimalOrDefault(analysis, "tax_amount", BigDecimal.ZERO)); + parmerters.put("royalpay_fee", takeDecimalOrDefault(analysis, "total_royalpay_fee", BigDecimal.ZERO)); + parmerters.put("incremental_fee", takeDecimalOrDefault(analysis, "total_incremental_surcharge", BigDecimal.ZERO)); + parmerters.put("incremental_gst", takeDecimalOrDefault(analysis, "total_incremental_tax", BigDecimal.ZERO)); + parmerters.put("royalpay_gst", analysis.getBigDecimal("tax_amount").subtract(analysis.getBigDecimal("total_incremental_tax")).setScale(2,RoundingMode.HALF_UP)); + parmerters.put("total_transaction_fee", analysis.getBigDecimal("total_transaction_fee").add(analysis.getBigDecimal("total_transaction_fee_tax")).setScale(2,RoundingMode.HALF_UP)); + parmerters.put("total_royalpay_fee", analysis.getBigDecimal("total_surcharge").subtract(parmerters.getBigDecimal("total_transaction_fee")).setScale(2,RoundingMode.HALF_UP)); + + dataList.parallelStream().forEach(item -> { + BigDecimal incrementalSurcharge = item.containsKey("incremental_surcharge") ? item.getBigDecimal("incremental_surcharge") : BigDecimal.ZERO; + BigDecimal taxAmount = item.containsKey("tax_amount") ? item.getBigDecimal("tax_amount") : BigDecimal.ZERO; + BigDecimal royalpaySurhcarge = item.containsKey("royal_surcharge") ? item.getBigDecimal("royal_surcharge") : BigDecimal.ZERO; + BigDecimal surhcargeBack = item.containsKey("surcharge_cashback") ? item.getBigDecimal("surcharge_cashback") : BigDecimal.ZERO; + BigDecimal channelSurcharge = item.containsKey("channel_surcharge") ? item.getBigDecimal("channel_surcharge") : BigDecimal.ZERO; + BigDecimal incrementalTax = incrementalSurcharge.divide(new BigDecimal(10), 2, RoundingMode.HALF_UP); + BigDecimal transactionFee = item.getBigDecimal("transaction_fee"); + BigDecimal transactionFeeTax = item.getBigDecimal("transaction_fee").divide(new BigDecimal(10), 2, RoundingMode.HALF_UP); + BigDecimal royalpayTax = taxAmount.subtract(incrementalTax).subtract(transactionFeeTax); + BigDecimal realRoyalpayCharge = item.getBigDecimal("total_surcharge").add(taxAmount).subtract(transactionFee).subtract(transactionFeeTax); + item.put("incremental_surcharge", incrementalSurcharge.add(incrementalTax).setScale(2, RoundingMode.HALF_UP)); + item.put("total_surcharge_intax", realRoyalpayCharge.setScale(2, RoundingMode.HALF_UP)); + item.put("transaction_fee_intax", transactionFee.add(transactionFeeTax).setScale(2,RoundingMode.HALF_UP)); + scaleDecimalVal(item, "display_amount", item.getString("currency")); + String platformCurrency = PlatformEnvironment.getEnv().getForeignCurrency(); + scaleDecimalVal(item, "clearing_amount", platformCurrency); + scaleDecimalVal(item, "settle_amount", platformCurrency); + scaleDecimalVal(item, "total_surcharge", platformCurrency); + }); + JRDataSource jrDataSource = new JRBeanCollectionDataSource(dataList); + response.setContentType("application/pdf"); + String fileName = client.getString("client_moniker") + "_Card_Payment_" + parmerters.getString("dateRange").replaceAll("/", ""); + response.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ".pdf"); + OutputStream outs = response.getOutputStream(); +// JSONObject clientIncrement = clientIncrementalMapper.findByClinetIdAndChannel(client.getIntValue("client_id"), "RP跨境商城"); +// InputStream jasper = clientIncrement == null ? trans_flow.getInputStream() : incremental_trans_flow.getInputStream(); + InputStream jasper = upay_trans_flow.getInputStream(); + byte[] bytes = JasperRunManager.runReportToPdf(jasper, parmerters, jrDataSource); + outs.write(bytes, 0, bytes.length); + outs.flush(); + outs.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + } + @Override public void exportTransFlowApi(TradeLogQuery query, JSONObject partner, HttpServletResponse response) throws Exception { query.setClearing_status(-1); diff --git a/src/main/java/au/com/royalpay/payment/manage/tradelog/web/TradeFlowController.java b/src/main/java/au/com/royalpay/payment/manage/tradelog/web/TradeFlowController.java index 42c2660fa..ea744807d 100644 --- a/src/main/java/au/com/royalpay/payment/manage/tradelog/web/TradeFlowController.java +++ b/src/main/java/au/com/royalpay/payment/manage/tradelog/web/TradeFlowController.java @@ -39,6 +39,12 @@ public class TradeFlowController { tradeLogService.exportTransFlow(query, partner, httpResponse); } + @PartnerMapping(value = "/report/upay_pdf", method = RequestMethod.GET) + @ReadOnlyConnection + public void exportUpayPDF(TradeLogQuery query, @ModelAttribute(CommonConsts.PARTNER_STATUS) JSONObject partner, HttpServletResponse httpResponse) throws Exception { + tradeLogService.exportUpayTransFlow(query, partner, httpResponse); + } + @PartnerMapping(value = "/report/excel", method = RequestMethod.GET) @ReadOnlyConnection public void exportExcel(TradeLogQuery query, @ModelAttribute(CommonConsts.PARTNER_STATUS) JSONObject partner, HttpServletResponse httpResponse) throws Exception { diff --git a/src/main/resources/au/com/royalpay/payment/manage/mappers/payment/TransactionMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/mappers/payment/TransactionMapper.xml index a71c233a1..a4ee7285c 100644 --- a/src/main/resources/au/com/royalpay/payment/manage/mappers/payment/TransactionMapper.xml +++ b/src/main/resources/au/com/royalpay/payment/manage/mappers/payment/TransactionMapper.xml @@ -576,9 +576,11 @@ (SELECT min(r.rate_value) FROM sys_client_rates r WHERE r.client_id = t.client_id AND date(r.expiry_time) >= DATE(t.clearing_time) AND date(r.active_time) <= DATE(t.clearing_time)) rate, - t.clearing_order clear_detail_id + t.clearing_order clear_detail_id, + lc.balance_group FROM pmt_transactions t left join log_clearing_detail cd on cd.clear_detail_id=t.clearing_order + left join log_clearing lc on cd.clearing_id = lc.clearing_id left join sys_clients sc on t.client_id = sc.client_id WHERE t.channel='Settlement' diff --git a/src/main/resources/jasper/partner_upay_invoice_gst.jasper b/src/main/resources/jasper/partner_upay_invoice_gst.jasper new file mode 100644 index 0000000000000000000000000000000000000000..e017ea27964d50fd889e437919069bd62738e221 GIT binary patch literal 83133 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 literal 0 HcmV?d00001 diff --git a/src/main/ui/static/analysis/clearing-log.js b/src/main/ui/static/analysis/clearing-log.js index ab825af23..60993ba21 100644 --- a/src/main/ui/static/analysis/clearing-log.js +++ b/src/main/ui/static/analysis/clearing-log.js @@ -556,6 +556,10 @@ define(['angular', 'decimal', 'uiBootstrap', 'uiRouter', 'angularEcharts'], func return '/static/images/yeepay_sign_lg.png'; case 'LakalaPay': return '/static/images/lakalapay_sign_lg.png'; + case 'rpaypmt_card': + return '/static/images/card_payment_sign_lg.png'; + case 'rpaypmt_dd': + return '/static/images/direct_debit_sign_lg.png'; } } }); diff --git a/src/main/ui/static/analysis/templates/settlement_transactions.html b/src/main/ui/static/analysis/templates/settlement_transactions.html index 4b118af1c..4126077bc 100644 --- a/src/main/ui/static/analysis/templates/settlement_transactions.html +++ b/src/main/ui/static/analysis/templates/settlement_transactions.html @@ -53,6 +53,16 @@ +
  • + + + +
  • +
  • + + + +
  • diff --git a/src/main/ui/static/commons/services/clearingDetailService.js b/src/main/ui/static/commons/services/clearingDetailService.js index 7d347e1cf..7e0bd7faa 100644 --- a/src/main/ui/static/commons/services/clearingDetailService.js +++ b/src/main/ui/static/commons/services/clearingDetailService.js @@ -87,6 +87,10 @@ define(['../app','decimal'], function (app,Decimal) { return '/static/images/hf_sign_lg.png'; case 'Rpay': return '/static/images/rpayplus_sign_lg.png'; + case 'rpaypmt_card': + return '/static/images/card_payment_sign_lg.png'; + case 'rpaypmt_dd': + return '/static/images/direct_debit_sign_lg.png'; } } }); diff --git a/src/main/ui/static/config/bdprize/bdprize.js b/src/main/ui/static/config/bdprize/bdprize.js index 46acd352f..eaac60668 100644 --- a/src/main/ui/static/config/bdprize/bdprize.js +++ b/src/main/ui/static/config/bdprize/bdprize.js @@ -415,6 +415,10 @@ define(['angular', '../../analysis/bd/analysis-bd'], function (angular) { return '/static/images/yeepay_sign_lg.png'; case 'LakalaPay': return '/static/images/lakalapay_sign_lg.png'; + case 'rpaypmt_card': + return '/static/images/card_payment_sign_lg.png'; + case 'rpaypmt_dd': + return '/static/images/direct_debit_sign_lg.png'; } } }); diff --git a/src/main/ui/static/payment/partner/partner-manage.js b/src/main/ui/static/payment/partner/partner-manage.js index 20874bac1..db73e6dfc 100644 --- a/src/main/ui/static/payment/partner/partner-manage.js +++ b/src/main/ui/static/payment/partner/partner-manage.js @@ -3658,9 +3658,53 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter app.controller('partnerMWAuthFileCtrl', ['$scope', '$http', '$rootScope', 'commonDialog', '$state', 'Upload', 'file', function ($scope, $http, $rootScope, commonDialog, $state, Upload, file) { $scope.id_info_form = {edit: false}; $scope.file = file.data || {}; + $scope.uploadFile = {}; $scope.file.upay_risk_level = $scope.partner.upay_risk_level; $scope.file.upay_risk_remark = $scope.partner.upay_risk_remark; - $scope.uploadApplyFile = function (file) { + + $scope.bankIsImage = true; + $scope.asicIsImage = true; + $scope.idIsImage = true; + $scope.utilityIsImage = true; + $scope.refundIsImage = true; + $scope.privacyIsImage = true; + $scope.cardIsImage = true; + $scope.letterIsImage = true; + $scope.promotionalIsImage = true; + $scope.termsIsImage = true; + if ($scope.file.client_bank_file && $scope.file.client_bank_file.endsWith('pdf')) { + $scope.bankIsImage = false; + } + if ($scope.file.client_company_file && $scope.file.client_company_file.endsWith('pdf')) { + $scope.asicIsImage = false; + } + if ($scope.file.upay_driver_license && $scope.file.upay_driver_license.endsWith('pdf')) { + $scope.idIsImage = false; + } + if ($scope.file.kyc_utility_bill_file && $scope.file.kyc_utility_bill_file.endsWith('pdf')) { + $scope.utilityIsImage = false; + } + if ($scope.file.refund_exchange_policy && $scope.file.refund_exchange_policy.endsWith('pdf')) { + $scope.refundIsImage = false; + } + if ($scope.file.upay_privacy_policy && $scope.file.upay_privacy_policy.endsWith('pdf')) { + $scope.privacyIsImage = false; + } + if ($scope.file.card_security_policy && $scope.file.card_security_policy.endsWith('pdf')) { + $scope.cardIsImage = false; + } + if ($scope.file.upay_offer_letter && $scope.file.upay_offer_letter.endsWith('pdf')) { + $scope.letterIsImage = false; + } + if ($scope.file.upay_promotional_offer && $scope.file.upay_promotional_offer.endsWith('pdf')) { + $scope.promotionalIsImage = false; + } + if ($scope.file.upay_terms_conditions && $scope.file.upay_terms_conditions.endsWith('pdf')) { + $scope.termsIsImage = false; + } + + + $scope.uploadBankFile = function (file) { if (file != null) { if (file.size > 3 * 1024 * 1024) { commonDialog.alert({title: 'Error', content: '文件大小不能超过3MB,请压缩后重试', type: 'error'}) @@ -3670,10 +3714,12 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter url: '/attachment/files', data: {file: file} }).then(function (resp) { + $scope.uploadFile = {}; delete $scope.bankFileProgress; - $scope.file.upay_application_form = resp.data.url; + $scope.file.client_bank_file = resp.data.url; + $scope.uploadFile.client_bank_file = resp.data.url; $scope.updateFile(); - if ($scope.file.upay_application_form.endsWith('pdf')) { + if ($scope.file.client_bank_file.endsWith('pdf')) { $scope.bankIsImage = false; } else { $scope.bankIsImage = true; @@ -3687,136 +3733,268 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter } } }; - $scope.agreeIsImage = true; - if ($scope.file.file_agreement_info && $scope.file.file_agreement_info.endsWith('pdf')) { - $scope.agreeIsImage = false; - } - $scope.bankIsImage = true; - if ($scope.file.upay_application_form && $scope.file.upay_application_form.endsWith('pdf')) { - $scope.bankIsImage = false; - } - $scope.companyIsImage = true; - if ($scope.file.file_company_info && $scope.file.file_company_info.endsWith('pdf')) { - $scope.companyIsImage = false; - } - $scope.applyIsImage = true; - if ($scope.file.file_apply_info && $scope.file.file_apply_info.endsWith('pdf')) { - $scope.applyIsImage = false; - } - $scope.idIsImage = true; - if ($scope.file.file_id_info && $scope.file.file_id_info.endsWith('pdf')) { - $scope.idIsImage = false; - } - - $scope.uploadAgreementFile = function (file) { + $scope.uploadASICFile = function (file) { if (file != null) { if (file.size > 3 * 1024 * 1024) { commonDialog.alert({title: 'Error', content: '文件大小不能超过3MB,请压缩后重试', type: 'error'}) } else { - $scope.companyFileProgress = {value: 0}; + $scope.ASICProgress = {value: 0}; Upload.upload({ url: '/attachment/files', data: {file: file} }).then(function (resp) { - delete $scope.companyFileProgress; - $scope.file.upay_agreement_file = resp.data.url; + $scope.uploadFile = {}; + delete $scope.ASICProgress; + $scope.file.client_company_file = resp.data.url; + $scope.uploadFile.client_company_file = resp.data.url; $scope.updateFile(); - if ($scope.file.upay_agreement_file.endsWith('pdf')) { - $scope.companyIsImage = false; + if ($scope.file.client_company_file.endsWith('pdf')) { + $scope.bankIsImage = false; } else { - $scope.companyIsImage = true; + $scope.bankIsImage = true; } }, function (resp) { - delete $scope.companyFileProgress; + delete $scope.ASICProgress; commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) }, function (evt) { - $scope.companyFileProgress.value = parseInt(100 * evt.loaded / evt.total); + $scope.ASICProgress.value = parseInt(100 * evt.loaded / evt.total); }) } } }; - $scope.uploadOfferFile = function (file) { + $scope.uploadIdFile = function (file) { if (file != null) { if (file.size > 3 * 1024 * 1024) { commonDialog.alert({title: 'Error', content: '文件大小不能超过3MB,请压缩后重试', type: 'error'}) } else { - $scope.idFileProgress = {value: 0}; + $scope.idProgress = {value: 0}; Upload.upload({ url: '/attachment/files', data: {file: file} }).then(function (resp) { - delete $scope.idFileProgress; - $scope.file.upay_offer_letter = resp.data.url; + $scope.uploadFile = {}; + delete $scope.idProgress; + $scope.file.upay_driver_license = resp.data.url; + $scope.uploadFile.upay_driver_license = resp.data.url; $scope.updateFile(); - if ($scope.file.upay_offer_letter.endsWith('pdf')) { + if ($scope.file.upay_driver_license.endsWith('pdf')) { $scope.idIsImage = false; } else { $scope.idIsImage = true; } }, function (resp) { - delete $scope.idFileProgress; + delete $scope.idProgress; commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) }, function (evt) { - $scope.idFileProgress.value = parseInt(100 * evt.loaded / evt.total); + $scope.idProgress.value = parseInt(100 * evt.loaded / evt.total); }) } } }; - $scope.uploadDriverFile = function (file) { + $scope.uploadResidenceFile = function (file) { if (file != null) { - if (file.size > 10 * 1024 * 1024) { - commonDialog.alert({title: 'Error', content: '文件大小不能超过10MB,请压缩后重试', type: 'error'}) + if (file.size > 3 * 1024 * 1024) { + commonDialog.alert({title: 'Error', content: '文件大小不能超过3MB,请压缩后重试', type: 'error'}) } else { - $scope.agreementFileProgress = {value: 0}; + $scope.residenceFileProgress = {value: 0}; Upload.upload({ url: '/attachment/files', data: {file: file} }).then(function (resp) { - delete $scope.agreementFileProgress; - $scope.file.upay_driver_license = resp.data.url; + $scope.uploadFile = {}; + delete $scope.residenceFileProgress; + $scope.file.kyc_utility_bill_file = resp.data.url; + $scope.uploadFile.kyc_utility_bill_file = resp.data.url; $scope.updateFile(); - if ($scope.file.upay_driver_license.endsWith('pdf')) { - $scope.agreeIsImage = false; + if ($scope.file.kyc_utility_bill_file.endsWith('pdf')) { + $scope.utilityIsImage = false; } else { - $scope.agreeIsImage = true; + $scope.utilityIsImage = true; } }, function (resp) { - delete $scope.agreementFileProgress; + delete $scope.residenceFileProgress; commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) }, function (evt) { - $scope.agreementFileProgress.value = parseInt(100 * evt.loaded / evt.total); + $scope.residenceFileProgress.value = parseInt(100 * evt.loaded / evt.total); }) } } }; - $scope.uploadResidenceFile = function (file) { + $scope.uploadRefundPolicyFile = function (file) { if (file != null) { if (file.size > 3 * 1024 * 1024) { commonDialog.alert({title: 'Error', content: '文件大小不能超过3MB,请压缩后重试', type: 'error'}) } else { - $scope.applyFileProgress = {value: 0}; + $scope.refundPolicyFileProgress = {value: 0}; Upload.upload({ url: '/attachment/files', data: {file: file} }).then(function (resp) { - delete $scope.applyFileProgress; - $scope.file.upay_residence_certificate = resp.data.url; + $scope.uploadFile = {}; + delete $scope.refundPolicyFileProgress; + $scope.file.refund_exchange_policy = resp.data.url; + $scope.uploadFile.refund_exchange_policy = resp.data.url; $scope.updateFile(); - if ($scope.file.upay_residence_certificate.endsWith('pdf')) { - $scope.applyIsImage = false; + if ($scope.file.refund_exchange_policy.endsWith('pdf')) { + $scope.utilityIsImage = false; } else { - $scope.applyIsImage = true; + $scope.utilityIsImage = true; } }, function (resp) { - delete $scope.applyFileProgress; + delete $scope.refundPolicyFileProgress; commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) }, function (evt) { - $scope.applyFileProgress.value = parseInt(100 * evt.loaded / evt.total); + $scope.refundPolicyFileProgress.value = parseInt(100 * evt.loaded / evt.total); + }) + } + } + }; + $scope.uploadPrivacyPolicyFile = function (file) { + if (file != null) { + if (file.size > 3 * 1024 * 1024) { + commonDialog.alert({title: 'Error', content: '文件大小不能超过3MB,请压缩后重试', type: 'error'}) + } else { + $scope.privacyFileProgress = {value: 0}; + Upload.upload({ + url: '/attachment/files', + data: {file: file} + }).then(function (resp) { + $scope.uploadFile = {}; + delete $scope.privacyFileProgress; + $scope.file.upay_privacy_policy = resp.data.url; + $scope.uploadFile.upay_privacy_policy = resp.data.url; + $scope.updateFile(); + if ($scope.file.upay_privacy_policy.endsWith('pdf')) { + $scope.privacyIsImage = false; + } else { + $scope.privacyIsImage = true; + } + }, function (resp) { + delete $scope.privacyFileProgress; + commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) + }, function (evt) { + $scope.privacyFileProgress.value = parseInt(100 * evt.loaded / evt.total); }) - } } }; + $scope.uploadCardPolicyFile = function (file) { + if (file != null) { + if (file.size > 3 * 1024 * 1024) { + commonDialog.alert({title: 'Error', content: '文件大小不能超过3MB,请压缩后重试', type: 'error'}) + } else { + $scope.cardFileProgress = {value: 0}; + Upload.upload({ + url: '/attachment/files', + data: {file: file} + }).then(function (resp) { + $scope.uploadFile = {}; + delete $scope.cardFileProgress; + $scope.file.card_security_policy = resp.data.url; + $scope.uploadFile.card_security_policy = resp.data.url; + $scope.updateFile(); + if ($scope.file.card_security_policy.endsWith('pdf')) { + $scope.privacyIsImage = false; + } else { + $scope.privacyIsImage = true; + } + }, function (resp) { + delete $scope.cardFileProgress; + commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) + }, function (evt) { + $scope.cardFileProgress.value = parseInt(100 * evt.loaded / evt.total); + }) + } + } + }; + $scope.uploadLetterOfOfferFile = function (file) { + if (file != null) { + if (file.size > 3 * 1024 * 1024) { + commonDialog.alert({title: 'Error', content: '文件大小不能超过3MB,请压缩后重试', type: 'error'}) + } else { + $scope.letterFileProgress = {value: 0}; + Upload.upload({ + url: '/attachment/files', + data: {file: file} + }).then(function (resp) { + $scope.uploadFile = {}; + delete $scope.letterFileProgress; + $scope.file.upay_offer_letter = resp.data.url; + $scope.uploadFile.upay_offer_letter = resp.data.url; + $scope.updateFile(); + if ($scope.file.upay_offer_letter.endsWith('pdf')) { + $scope.letterIsImage = false; + } else { + $scope.letterIsImage = true; + } + }, function (resp) { + delete $scope.letterFileProgress; + commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) + }, function (evt) { + $scope.letterFileProgress.value = parseInt(100 * evt.loaded / evt.total); + }) + } + } + }; + $scope.uploadPromotionalFile = function (file) { + if (file != null) { + if (file.size > 3 * 1024 * 1024) { + commonDialog.alert({title: 'Error', content: '文件大小不能超过3MB,请压缩后重试', type: 'error'}) + } else { + $scope.promotionalFileProgress = {value: 0}; + Upload.upload({ + url: '/attachment/files', + data: {file: file} + }).then(function (resp) { + $scope.uploadFile = {}; + delete $scope.promotionalFileProgress; + $scope.file.upay_promotional_offer = resp.data.url; + $scope.uploadFile.upay_promotional_offer = resp.data.url; + $scope.updateFile(); + if ($scope.file.upay_promotional_offer.endsWith('pdf')) { + $scope.promotionalIsImage = false; + } else { + $scope.promotionalIsImage = true; + } + }, function (resp) { + delete $scope.promotionalFileProgress; + commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) + }, function (evt) { + $scope.promotionalFileProgress.value = parseInt(100 * evt.loaded / evt.total); + }) + } + } + }; + $scope.uploadTermsFile = function (file) { + if (file != null) { + if (file.size > 3 * 1024 * 1024) { + commonDialog.alert({title: 'Error', content: '文件大小不能超过3MB,请压缩后重试', type: 'error'}) + } else { + $scope.termsFileProgress = {value: 0}; + Upload.upload({ + url: '/attachment/files', + data: {file: file} + }).then(function (resp) { + $scope.uploadFile = {}; + delete $scope.termsFileProgress; + $scope.file.upay_terms_conditions = resp.data.url; + $scope.uploadFile.upay_terms_conditions = resp.data.url; + $scope.updateFile(); + if ($scope.file.upay_terms_conditions.endsWith('pdf')) { + $scope.termsIsImage = false; + } else { + $scope.termsIsImage = true; + } + }, function (resp) { + delete $scope.termsFileProgress; + commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) + }, function (evt) { + $scope.termsFileProgress.value = parseInt(100 * evt.loaded / evt.total); + }) + } + } + }; + $scope.saveIdInfo = function () { if (!$scope.file.upay_risk_level) { commonDialog.alert({title: 'Error', content: '请选择商户风险等级', type: 'error'}); @@ -3844,34 +4022,14 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter return url; }; - - $scope.deleteComplianceFiles = function (file_id) { - commonDialog.confirm({ - title: 'Warning', - content: 'This operation will delete the file, Are you sure?' - }).then(function () { - $http.put('/sys/partners/auth_file/' + file_id + '/delete').then(function (resp) { - commonDialog.alert({ - title: 'Success', - content: 'Delete Successful', - type: 'success' - }); - $state.reload(); - }, function (resp) { - commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); - }) - }) - }; - - $scope.updateFile = function () { - $http.put('/sys/partners/' + $scope.partner.client_moniker + '/mw_file', $scope.file).then(function () { + $http.put('/sys/partners/' + $scope.partner.client_moniker + '/mw_file', $scope.uploadFile).then(function () { commonDialog.alert({ title: 'Success', content: 'Upload Successful', type: 'success' }); - $state.reload(); + $state.go('partners.detail.files.MW_files', {reload: true}); }, function (resp) { commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); }) diff --git a/src/main/ui/static/payment/partner/templates/add_partner.html b/src/main/ui/static/payment/partner/templates/add_partner.html index 098a270da..8cdacf735 100644 --- a/src/main/ui/static/payment/partner/templates/add_partner.html +++ b/src/main/ui/static/payment/partner/templates/add_partner.html @@ -1290,7 +1290,7 @@
    -
    diff --git a/src/main/ui/static/payment/partner/templates/partner_auth_files.html b/src/main/ui/static/payment/partner/templates/partner_auth_files.html index c77dffeed..4a6289d53 100644 --- a/src/main/ui/static/payment/partner/templates/partner_auth_files.html +++ b/src/main/ui/static/payment/partner/templates/partner_auth_files.html @@ -3,18 +3,21 @@ width: 100%; } -
    -
    - + -
    -
    diff --git a/src/main/ui/static/payment/partner/templates/partner_cp_auth_files.html b/src/main/ui/static/payment/partner/templates/partner_cp_auth_files.html index 2d9035b04..2c927ce0e 100644 --- a/src/main/ui/static/payment/partner/templates/partner_cp_auth_files.html +++ b/src/main/ui/static/payment/partner/templates/partner_cp_auth_files.html @@ -4,7 +4,7 @@ } -
    Audit Files     +
    Audit Files     一键下载 diff --git a/src/main/ui/static/payment/partner/templates/partner_detail.html b/src/main/ui/static/payment/partner/templates/partner_detail.html index f36ca7470..c043063a9 100644 --- a/src/main/ui/static/payment/partner/templates/partner_detail.html +++ b/src/main/ui/static/payment/partner/templates/partner_detail.html @@ -474,13 +474,11 @@ ui-sref="partners.edit({clientMoniker:partner.client_moniker})"> Edit -
    -

    {{partner.client_moniker}} @@ -527,6 +525,12 @@

    +
    + +
    +

    +
    +
    @@ -815,6 +819,20 @@
    +
    + + +
    +

    +
    +
    +
    + + +
    +

    +
    +
    @@ -1238,6 +1256,36 @@ ng-if="$root.complianceCheck.clientInfo">
    +
    + +
    +

    + {{partner.mw_industry}} +

    + +
    +
    +
    + +
    + + + + + + +
    +
    diff --git a/src/main/ui/static/payment/partner/templates/partner_edit.html b/src/main/ui/static/payment/partner/templates/partner_edit.html index 0cecd2c54..b525a376f 100644 --- a/src/main/ui/static/payment/partner/templates/partner_edit.html +++ b/src/main/ui/static/payment/partner/templates/partner_edit.html @@ -1195,7 +1195,7 @@
    -
    diff --git a/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html b/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html index 371b91dbb..b3b301792 100644 --- a/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html +++ b/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html @@ -3,7 +3,7 @@ width: 100%; } -
    Audit Files     +
    Audit Files     一键下载 @@ -66,126 +66,173 @@
    - +
    - +
    - - - - - - -
    - - -
    + + +
    -
    - +
    - +
    - - - - - - -
    - - -
    + + + +
    -
    - +
    - +
    - - - - - -
    - - -
    + + + +
    - -
    -
    - -
    -
    - - - -
    - - - - - - -
    - - -
    +
    + +
    +
    + + +
    + + + +
    - -
    -
    - -
    -
    - - - -
    - - - - - - -
    - - -
    +
    + +
    +
    + + + +
    + + + + +
    +
    +
    + +
    +
    + + + +
    + + + + +
    +
    +
    + +
    +
    + + + +
    + + + + +
    +
    +
    + +
    +
    + + + +
    + + + + +
    +
    +
    + +
    +
    + + + +
    + + + + +
    +
    +
    + +
    +
    + + +
    + + + +
    diff --git a/src/main/ui/static/payment/partner/templates/partner_settlement.html b/src/main/ui/static/payment/partner/templates/partner_settlement.html index 32df9ee0a..a455f5aa6 100644 --- a/src/main/ui/static/payment/partner/templates/partner_settlement.html +++ b/src/main/ui/static/payment/partner/templates/partner_settlement.html @@ -220,6 +220,7 @@ Settle Time + Settle Version Transaction Amount to Merchant Service Fee @@ -229,11 +230,15 @@ - {{log.report_date}} + {{log.report_date|limitTo:10}}   + + Card Payment + Cross-border Payment + diff --git a/src/main/ui/static/payment/tradelog/templates/balance_report.html b/src/main/ui/static/payment/tradelog/templates/balance_report.html index aa142c3cd..c54962cbe 100644 --- a/src/main/ui/static/payment/tradelog/templates/balance_report.html +++ b/src/main/ui/static/payment/tradelog/templates/balance_report.html @@ -389,7 +389,8 @@
    diff --git a/src/main/ui/static/payment/tradelog/templates/partner_settlement_logs.html b/src/main/ui/static/payment/tradelog/templates/partner_settlement_logs.html index 2c18f8311..821e0d456 100644 --- a/src/main/ui/static/payment/tradelog/templates/partner_settlement_logs.html +++ b/src/main/ui/static/payment/tradelog/templates/partner_settlement_logs.html @@ -271,6 +271,7 @@ Date + Settle Version Transaction Amount(AUD) Transfer to Merchant(AUD) GST(AUD) @@ -285,6 +286,10 @@ {{log.clearing_time|limitTo:10}}   + + Card Payment + Cross-border Payment + diff --git a/src/main/ui/static/payment/tradelog/transflow.js b/src/main/ui/static/payment/tradelog/transflow.js index f58a24060..db1d86ed4 100644 --- a/src/main/ui/static/payment/tradelog/transflow.js +++ b/src/main/ui/static/payment/tradelog/transflow.js @@ -219,6 +219,9 @@ define(['angular', 'uiBootstrap', 'uiRouter'], function (angular) { if (type=='pdf'){ url = '/client/trans_flow/report/pdf'; } + if (type=='upay-pdf'){ + url = '/client/trans_flow/report/upay_pdf'; + } if (type=='excel'){ url='/client/trans_flow/report/excel'; } From 7dfb2f341b86952e693a6b2490173dd2782c6308 Mon Sep 17 00:00:00 2001 From: luoyang Date: Tue, 28 Apr 2020 11:00:54 +0800 Subject: [PATCH 10/40] =?UTF-8?q?add=20upay=20=E5=95=86=E6=88=B7invoice?= =?UTF-8?q?=E3=80=81settlement=20logs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commons/services/clearingDetailService.js | 30 ++ .../tradelog/partner-settlement-log.js | 3 + .../tradelog/templates/balance_report.html | 2 +- .../templates/partner_settlement_logs.html | 13 + ...partner_settlement_upay_settle_dialog.html | 258 ++++++++++++++++++ 5 files changed, 305 insertions(+), 1 deletion(-) create mode 100644 src/main/ui/static/payment/tradelog/templates/partner_settlement_upay_settle_dialog.html diff --git a/src/main/ui/static/commons/services/clearingDetailService.js b/src/main/ui/static/commons/services/clearingDetailService.js index 7e0bd7faa..1acf1105a 100644 --- a/src/main/ui/static/commons/services/clearingDetailService.js +++ b/src/main/ui/static/commons/services/clearingDetailService.js @@ -19,6 +19,21 @@ define(['../app','decimal'], function (app,Decimal) { size: 'lg' }) } + function openDetailOfUpaySettle(url, is_partner, client_id, detailId) { + $uibModal.open({ + templateUrl: '/static/payment/tradelog/templates/partner_settlement_upay_settle_dialog.html', + controller: 'clearingDetailOfUpaySettleCtrl', + resolve: { + detail: ['$http', function ($http) { + return $http.get(url); + }], + is_partner: is_partner, + client_id: client_id, + detailId: detailId + }, + size: 'lg' + }) + } function openDetailOfMergeSettle(url,client_id) { $uibModal.open({ templateUrl: '/static/payment/tradelog/templates/partner_settlement_merge_settle_dialog.html', @@ -37,6 +52,9 @@ define(['../app','decimal'], function (app,Decimal) { clientClearingDetail: function (client_id, detailId, is_partner) { openDetail('/client/clean_logs/' + client_id + '/settlement_logs/' + detailId, is_partner,client_id,detailId); }, + clientClearingDetailOfUpaySettle: function (client_id, detailId, is_partner) { + openDetailOfUpaySettle('/client/clean_logs/' + client_id + '/settlement_logs/' + detailId, is_partner,client_id,detailId); + }, clientClearingDetailOfMergeSettle: function (client_id, reportDate) { openDetailOfMergeSettle('/client/clean_logs/' + client_id + '/settlement_logs/report_date/' + reportDate, client_id); } @@ -55,6 +73,18 @@ define(['../app','decimal'], function (app,Decimal) { } $scope.channelAndDayOfAnalysis(); }]); + app.controller('clearingDetailOfUpaySettleCtrl', ['$scope', 'detail', 'is_partner','client_id','detailId','$http', function ($scope, detail, is_partner,client_id,detailId,$http) { + $scope.ctrl = {channel: null,day:null}; + $scope.report = detail.data; + $scope.is_partner = is_partner; + $scope.channelAndDayOfAnalysis = function () { + $http.get('/client/clean_logs/' + client_id + '/settlement_logs/' + detailId+'/analysis/'+$scope.ctrl.channel).then(function (resp) { + $scope.channelAndDayMap = resp.data; + $scope.index = 0; + }) + } + $scope.channelAndDayOfAnalysis(); + }]); app.controller('clearingDetailOfMergeSettleCtrl', ['$scope', 'detail','client_id','$http', function ($scope, detail,client_id,$http) { $scope.ctrl = {channel: null,day:null}; $scope.report = detail.data; diff --git a/src/main/ui/static/payment/tradelog/partner-settlement-log.js b/src/main/ui/static/payment/tradelog/partner-settlement-log.js index 0a0705f81..fd4179fe1 100644 --- a/src/main/ui/static/payment/tradelog/partner-settlement-log.js +++ b/src/main/ui/static/payment/tradelog/partner-settlement-log.js @@ -222,6 +222,9 @@ define(['angular', 'uiBootstrap', 'uiRouter'], function (angular) { $scope.getClearingTransactions = function (client_id, detailId) { clearingDetailService.clientClearingDetail(client_id, detailId, true) } + $scope.getClearingTransactionsOfUpaySettle = function (client_id, detailId) { + clearingDetailService.clientClearingDetailOfUpaySettle(client_id, detailId, true) + } $scope.getClearingTransactionsOfMergeSettle = function (client_id, reportDate) { clearingDetailService.clientClearingDetailOfMergeSettle(client_id, reportDate) } diff --git a/src/main/ui/static/payment/tradelog/templates/balance_report.html b/src/main/ui/static/payment/tradelog/templates/balance_report.html index c54962cbe..896b3fc43 100644 --- a/src/main/ui/static/payment/tradelog/templates/balance_report.html +++ b/src/main/ui/static/payment/tradelog/templates/balance_report.html @@ -390,7 +390,7 @@
    + From 432ea24894ef33eca7386891d88c33187afe2e7e Mon Sep 17 00:00:00 2001 From: luoyang Date: Tue, 28 Apr 2020 11:35:00 +0800 Subject: [PATCH 11/40] add citypartner support && upay application form --- .../impls/CityPartnerPrizeServiceImpl.java | 111 ++++-------------- .../beans/ClientMWAuthFilesInfo.java | 9 ++ .../core/impls/ClientManagerImpl.java | 1 + .../merchants/enums/UPayAuthFileEnum.java | 6 +- .../mappers/payment/TransactionMapper.xml | 4 +- .../static/payment/partner/partner-manage.js | 35 +++++- .../templates/partner_mw_auth_files.html | 17 +++ 7 files changed, 93 insertions(+), 90 deletions(-) diff --git a/src/main/java/au/com/royalpay/payment/manage/citypartner/core/impls/CityPartnerPrizeServiceImpl.java b/src/main/java/au/com/royalpay/payment/manage/citypartner/core/impls/CityPartnerPrizeServiceImpl.java index 349aa4013..50abd1285 100644 --- a/src/main/java/au/com/royalpay/payment/manage/citypartner/core/impls/CityPartnerPrizeServiceImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/citypartner/core/impls/CityPartnerPrizeServiceImpl.java @@ -1,88 +1,39 @@ package au.com.royalpay.payment.manage.citypartner.core.impls; -import java.io.IOException; -import java.io.OutputStream; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; -import javax.swing.plaf.basic.BasicScrollPaneUI; - -import au.com.royalpay.payment.manage.mappers.system.ClientBankAccountMapper; -import au.com.royalpay.payment.manage.mappers.system.ClientRateMapper; -import au.com.royalpay.payment.tools.CommonConsts; -import au.com.royalpay.payment.tools.merchants.core.MerchantInfoProvider; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.RandomStringUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.time.DateFormatUtils; -import org.apache.commons.lang3.time.DateUtils; -import org.apache.poi.hssf.usermodel.HSSFCellStyle; -import org.apache.poi.hssf.usermodel.HSSFFont; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.util.HSSFColor; -import org.apache.poi.ss.usermodel.*; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import com.alibaba.fastjson.JSONObject; - import au.com.royalpay.payment.manage.citypartner.beans.AgentCommissionAnalysis; import au.com.royalpay.payment.manage.citypartner.beans.CityPartnerCommissionAnalysis; import au.com.royalpay.payment.manage.citypartner.beans.ReferrerCommissionAnalysis; import au.com.royalpay.payment.manage.citypartner.core.CityPartnerPrizeService; -import au.com.royalpay.payment.manage.mappers.financial.FinancialAgentCommissionDetailMapper; -import au.com.royalpay.payment.manage.mappers.financial.FinancialAgentCommissionMapper; -import au.com.royalpay.payment.manage.mappers.financial.FinancialPartnerCommissionDetailMapper; -import au.com.royalpay.payment.manage.mappers.financial.FinancialPartnerCommissionMapper; -import au.com.royalpay.payment.manage.mappers.financial.FinancialReferrerCommissionDetailMapper; -import au.com.royalpay.payment.manage.mappers.financial.FinancialReferrerCommissionMapper; -import au.com.royalpay.payment.manage.mappers.financial.FinancialSeniorPartnerCommissionDetailMapper; -import au.com.royalpay.payment.manage.mappers.financial.FinancialSeniorPartnerCommissionMapper; +import au.com.royalpay.payment.manage.mappers.financial.*; import au.com.royalpay.payment.manage.mappers.payment.TransactionMapper; import au.com.royalpay.payment.manage.mappers.system.OrgMapper; import au.com.royalpay.payment.tools.CommonConsts; import au.com.royalpay.payment.tools.env.SysConfigManager; import au.com.royalpay.payment.tools.exceptions.BadRequestException; import au.com.royalpay.payment.tools.exceptions.ServerErrorException; - +import au.com.royalpay.payment.tools.merchants.core.MerchantInfoProvider; import com.alibaba.fastjson.JSONObject; - import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.commons.lang3.time.DateUtils; +import org.apache.poi.hssf.usermodel.HSSFCellStyle; +import org.apache.poi.hssf.usermodel.HSSFFont; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hssf.util.HSSFColor; +import org.apache.poi.ss.usermodel.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.OutputStream; import java.math.BigDecimal; +import java.math.RoundingMode; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; /** * Created by yixian on 2017-03-08. @@ -476,6 +427,7 @@ public class CityPartnerPrizeServiceImpl implements CityPartnerPrizeService { BigDecimal total_surage = BigDecimal.ZERO; BigDecimal net_surage = BigDecimal.ZERO; BigDecimal royalpay_surage = BigDecimal.ZERO; + BigDecimal transaction_fee = BigDecimal.ZERO; JSONObject json = new JSONObject(); String channel = oneChannel.getKey(); if ("hf".equals(oneChannel.getKey().toLowerCase()) || "yeepay".equals(oneChannel.getKey().toLowerCase()) || "lakalapay".equals(oneChannel.getKey().toLowerCase())) { @@ -491,7 +443,7 @@ public class CityPartnerPrizeServiceImpl implements CityPartnerPrizeService { for (JSONObject params : oneChannel.getValue()) { BigDecimal tmpClearingAmount = params.getBooleanValue("customer_surcharge") ? params.getBigDecimal("settle_amount") : params.getBigDecimal("clearing_amount"); BigDecimal channelRate = params.get("org_rate") != null ? params.getBigDecimal("org_rate") : (orgInfo.getBigDecimal(channel.toLowerCase() + "_rate_value").divide(CommonConsts.HUNDRED, 4, RoundingMode.DOWN)); - BigDecimal tmpTotalSurcharge = params.getBigDecimal("total_surcharge").subtract(params.getBigDecimal("surcharge_cashback")); + BigDecimal tmpTotalSurcharge = params.getBigDecimal("total_surcharge").subtract(params.getBigDecimal("surcharge_cashback")).subtract(params.getBigDecimal("transaction_fee")); //增加货币判断 int i = currencyScale(params.getString("clearing_currency")); total = total.add(tmpClearingAmount); @@ -499,11 +451,13 @@ public class CityPartnerPrizeServiceImpl implements CityPartnerPrizeService { royalpay_surage = royalpay_surage.add(tmpClearingAmount.multiply(channelRate).setScale(i, RoundingMode.HALF_UP)); // net_surage = net_surage.add(getThirdPartyCharge(params.getString("channel"), params.getBigDecimal("clearing_amount"), channelCharge)); net_surage = net_surage.add(params.getBigDecimal("channel_surcharge")); + transaction_fee = transaction_fee.add(params.getBigDecimal("transaction_fee")); } BigDecimal org_charge = total_surage.subtract(royalpay_surage); json.put("channel", oneChannel.getKey()); json.put("gross_amount", total); json.put("total_charge", total_surage); + json.put("transaction_fee", transaction_fee); json.put("net_charge", net_surage); json.put("org_rate", orgInfo.getBigDecimal(channel.toLowerCase() + "_rate_value")); json.put("royalpay_charge", royalpay_surage); @@ -525,6 +479,7 @@ public class CityPartnerPrizeServiceImpl implements CityPartnerPrizeService { BigDecimal net_surage = BigDecimal.ZERO; BigDecimal royalpay_surage = BigDecimal.ZERO; BigDecimal share_surage = BigDecimal.ZERO; + BigDecimal transaction_fee = BigDecimal.ZERO; JSONObject json = new JSONObject(); String channel = oneChannel.getKey(); @@ -534,7 +489,7 @@ public class CityPartnerPrizeServiceImpl implements CityPartnerPrizeService { for (JSONObject params : oneChannel.getValue()) { BigDecimal tmpClearingAmount = params.getBooleanValue("customer_surcharge") ? params.getBigDecimal("settle_amount") : params.getBigDecimal("clearing_amount"); BigDecimal channelRate = params.get("org_rate") != null ? params.getBigDecimal("org_rate") : (orgInfo.getBigDecimal(channel.toLowerCase() + "_rate_value").divide(CommonConsts.HUNDRED, 4, RoundingMode.DOWN)); - BigDecimal tmpTotalSurcharge = params.getBigDecimal("total_surcharge").subtract(params.getBigDecimal("surcharge_cashback")); + BigDecimal tmpTotalSurcharge = params.getBigDecimal("total_surcharge").subtract(params.getBigDecimal("surcharge_cashback")).subtract(params.getBigDecimal("transaction_fee")); //增加货币判断 int i = currencyScale(params.getString("clearing_currency")); BigDecimal parent_surage = tmpClearingAmount.multiply(parentOrgInfo.getBigDecimal(channel.toLowerCase() + "_rate_value").divide(CommonConsts.HUNDRED, 4, RoundingMode.DOWN)).setScale(i, RoundingMode.HALF_UP); @@ -545,6 +500,7 @@ public class CityPartnerPrizeServiceImpl implements CityPartnerPrizeService { //net_surage = net_surage.add(getThirdPartyCharge(params.getString("channel"), params.getBigDecimal("clearing_amount"), channelCharge)); net_surage = net_surage.add(params.getBigDecimal("channel_surcharge")); share_surage = share_surage.add(roy_surage.subtract(parent_surage)).setScale(i, RoundingMode.HALF_UP); + transaction_fee = transaction_fee.add(params.getBigDecimal("transaction_fee")); } BigDecimal org_charge = total_surage.subtract(royalpay_surage); @@ -556,6 +512,7 @@ public class CityPartnerPrizeServiceImpl implements CityPartnerPrizeService { json.put("partner_charge", royalpay_surage); json.put("share_charge", share_surage); json.put("org_charge", org_charge); + json.put("transaction_fee", transaction_fee); json.put("commission_type", "1"); json.put("create_time", new Date()); amountByChannel.add(json); @@ -579,6 +536,7 @@ public class CityPartnerPrizeServiceImpl implements CityPartnerPrizeService { BigDecimal total_surage = BigDecimal.ZERO; BigDecimal net_surage = BigDecimal.ZERO; BigDecimal royalpay_surage = BigDecimal.ZERO; + BigDecimal transaction_fee = BigDecimal.ZERO; Date datefrom = new Date(); Date dateto = new Date(); JSONObject json = new JSONObject(); @@ -617,6 +575,7 @@ public class CityPartnerPrizeServiceImpl implements CityPartnerPrizeService { royalpay_surage = royalpay_surage.add(tmpClearingAmount.multiply(channelRate).setScale(i, RoundingMode.HALF_UP)); //net_surage = net_surage.add(getThirdPartyCharge(params.getString("channel"), params.getBigDecimal("clearing_amount"), channelCharge)); net_surage = net_surage.add(params.getBigDecimal("channel_surcharge")); + transaction_fee = transaction_fee.add(params.getBigDecimal("transaction_fee")); } BigDecimal org_charge = total_surage.subtract(royalpay_surage); if (channel.toLowerCase().equals("alipay_direct")) { @@ -642,6 +601,7 @@ public class CityPartnerPrizeServiceImpl implements CityPartnerPrizeService { json.put("org_net_charge", net_surage); } json.put("org_charge", org_charge); + json.put("transaction_fee", transaction_fee); json.put("commission_type", "1"); json.put("create_time", new Date()); json.put("date_from", DateFormatUtils.format(datefrom, "yyyy-MM-dd")); @@ -825,6 +785,7 @@ public class CityPartnerPrizeServiceImpl implements CityPartnerPrizeService { temp.put("total_charge", 0); temp.put("royalpay_charge", 0); temp.put("org_charge", 0); + temp.put("transaction_fee", 0); temp.put("share_charge", 0); temp.put("channel", channel.getString("channel")); temp.put("net_charge", 0); @@ -839,28 +800,8 @@ public class CityPartnerPrizeServiceImpl implements CityPartnerPrizeService { mineCommission.put("share_charge", mineCommission.getBigDecimal("share_charge").subtract(channel.getBigDecimal("share_charge"))); financialPartnerCommissionMapper.update(mineCommission); } - channel.put("month", month); - channel.put("year", year); - channel.put("org_id", orgId); - //撤销agent表 -// financialAgentCommissionMapper.save(channel); } } - //撤销agent表 -// Map> groupByClientMap = transactionDetail.stream().collect(Collectors.groupingBy(e -> e.getInteger("client_id"))); -// for (Map.Entry> oneClient : groupByClientMap.entrySet()) { -// -// JSONObject org = orgMapper.findOne(oneClient.getValue().get(0).getInteger("org_id")); -// Map> groupByChannel = oneClient.getValue().stream().collect(Collectors.groupingBy(e -> e.getString("channel"))); -// -// List clientChannelAmount = clientChannelAmount(oneClient.getKey(),org, groupByChannel, channelCharge,year,month,2); -// for (JSONObject channel : clientChannelAmount) { -// financialAgentCommissionDetailMapper.save(channel); -// } -// -// } - - } @Override diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientMWAuthFilesInfo.java b/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientMWAuthFilesInfo.java index 45235245c..73f0db163 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientMWAuthFilesInfo.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientMWAuthFilesInfo.java @@ -19,6 +19,7 @@ public class ClientMWAuthFilesInfo { private String kyc_utility_bill_file; private String upay_risk_level; private String upay_risk_remark; + private String upay_application_form; public JSONObject toJson(){ return (JSONObject)JSONObject.toJSON(this); @@ -130,4 +131,12 @@ public class ClientMWAuthFilesInfo { public void setKyc_utility_bill_file(String kyc_utility_bill_file) { this.kyc_utility_bill_file = kyc_utility_bill_file; } + + public void setUpay_application_form(String upay_application_form) { + this.upay_application_form = upay_application_form; + } + + public String getUpay_application_form() { + return upay_application_form; + } } diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index 56088735f..1482ad7a6 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -3932,6 +3932,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.UPAY_PROMOTIONAL_OFFER.getFileName(), filesInfo.getUpay_promotional_offer()); updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.UPAY_TERMS_CONDITIONS.getFileName(), filesInfo.getUpay_terms_conditions()); updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.KYC_UTILITY_BILL_FILE.getFileName(), filesInfo.getKyc_utility_bill_file()); + updateSysMWClientFiles(manager, clientId, UPayAuthFileEnum.UPAY_APPLICATION_FORM.getFileName(), filesInfo.getUpay_application_form()); } catch (Exception e) { logger.error("上传合规文件失败", e); } diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/enums/UPayAuthFileEnum.java b/src/main/java/au/com/royalpay/payment/manage/merchants/enums/UPayAuthFileEnum.java index 992e1280c..202a44d5f 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/enums/UPayAuthFileEnum.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/enums/UPayAuthFileEnum.java @@ -11,7 +11,8 @@ public enum UPayAuthFileEnum { UPAY_OFFER_LETTER("upay_offer_letter"), UPAY_PROMOTIONAL_OFFER("upay_promotional_offer"), UPAY_TERMS_CONDITIONS("upay_terms_conditions"), - KYC_UTILITY_BILL_FILE("kyc_utility_bill_file"); + KYC_UTILITY_BILL_FILE("kyc_utility_bill_file"), + UPAY_APPLICATION_FORM("upay_application_form"); private final String fileName; @@ -33,6 +34,7 @@ public enum UPayAuthFileEnum { UPAY_OFFER_LETTER.getFileName(), UPAY_PROMOTIONAL_OFFER.getFileName(), UPAY_TERMS_CONDITIONS.getFileName(), - KYC_UTILITY_BILL_FILE.getFileName()}; + KYC_UTILITY_BILL_FILE.getFileName(), + UPAY_APPLICATION_FORM.getFileName()}; } } diff --git a/src/main/resources/au/com/royalpay/payment/manage/mappers/payment/TransactionMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/mappers/payment/TransactionMapper.xml index a4ee7285c..38e1504a7 100644 --- a/src/main/resources/au/com/royalpay/payment/manage/mappers/payment/TransactionMapper.xml +++ b/src/main/resources/au/com/royalpay/payment/manage/mappers/payment/TransactionMapper.xml @@ -940,6 +940,7 @@ t.transaction_time, if(t.transaction_type = 'Credit', t.clearing_amount, -t.clearing_amount) clearing_amount, if(t.transaction_type = 'Credit', t.total_surcharge, -t.total_surcharge) total_surcharge, + if(t.transaction_type = 'Credit', t.transaction_fee, -t.transaction_fee) transaction_fee, if(t.transaction_type = 'Credit', t.channel_surcharge, -t.channel_surcharge) channel_surcharge, if(t.transaction_type = 'Credit', t.settle_amount, -t.settle_amount) settle_amount, t.order_id, @@ -967,12 +968,13 @@ t.transaction_time, if(t.transaction_type = 'Credit', t.clearing_amount, -t.clearing_amount) clearing_amount, if(t.transaction_type = 'Credit', t.total_surcharge, -t.total_surcharge) total_surcharge, + if(t.transaction_type = 'Credit', t.transaction_fee, -t.transaction_fee) transaction_fee, if(t.transaction_type = 'Credit', t.channel_surcharge, -t.channel_surcharge) channel_surcharge, if(t.transaction_type = 'Credit', t.settle_amount, -t.settle_amount) settle_amount, t.order_id, t.org_rate, t.surcharge_cashback, - o.customer_surcharge + o.customer_surcharge, from pmt_transactions t LEFT JOIN pmt_orders o on o.order_id = t.order_id INNER JOIN sys_org so ON t.org_id = so.org_id AND so.is_valid = 1 diff --git a/src/main/ui/static/payment/partner/partner-manage.js b/src/main/ui/static/payment/partner/partner-manage.js index db73e6dfc..6bc6cf720 100644 --- a/src/main/ui/static/payment/partner/partner-manage.js +++ b/src/main/ui/static/payment/partner/partner-manage.js @@ -3672,6 +3672,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter $scope.letterIsImage = true; $scope.promotionalIsImage = true; $scope.termsIsImage = true; + $scope.applicationIsImage = true; if ($scope.file.client_bank_file && $scope.file.client_bank_file.endsWith('pdf')) { $scope.bankIsImage = false; } @@ -3702,8 +3703,38 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter if ($scope.file.upay_terms_conditions && $scope.file.upay_terms_conditions.endsWith('pdf')) { $scope.termsIsImage = false; } - - + if ($scope.file.upay_application_form && $scope.file.upay_application_form.endsWith('pdf')) { + $scope.applicationIsImage = false; + } + $scope.uploadApplicationFile = function (file) { + if (file != null) { + if (file.size > 3 * 1024 * 1024) { + commonDialog.alert({title: 'Error', content: '文件大小不能超过3MB,请压缩后重试', type: 'error'}) + } else { + $scope.applicationFileProgress = {value: 0}; + Upload.upload({ + url: '/attachment/files', + data: {file: file} + }).then(function (resp) { + $scope.uploadFile = {}; + delete $scope.applicationFileProgress; + $scope.file.upay_application_form = resp.data.url; + $scope.uploadFile.upay_application_form = resp.data.url; + $scope.updateFile(); + if ($scope.file.upay_application_form.endsWith('pdf')) { + $scope.bankIsImage = false; + } else { + $scope.bankIsImage = true; + } + }, function (resp) { + delete $scope.applicationFileProgress; + commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) + }, function (evt) { + $scope.applicationFileProgress.value = parseInt(100 * evt.loaded / evt.total); + }) + } + } + }; $scope.uploadBankFile = function (file) { if (file != null) { if (file.size > 3 * 1024 * 1024) { diff --git a/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html b/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html index b3b301792..64e766aa7 100644 --- a/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html +++ b/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html @@ -65,6 +65,23 @@
    +
    + +
    +
    + + + +
    + + + + +
    +
    From 9d9499cfc84207752670f46623cd51e0558a8a3e Mon Sep 17 00:00:00 2001 From: luoyang Date: Tue, 28 Apr 2020 11:52:04 +0800 Subject: [PATCH 12/40] =?UTF-8?q?add=20card=20=E5=BC=80=E9=80=9A=E9=82=AE?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/impls/ClientManagerImpl.java | 25 +++++-------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index 1482ad7a6..f44f84a20 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -1216,9 +1216,6 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid int clientId = client.getIntValue("client_id"); isRiskyMerchant(client, clientBankAccountMapper.clientBankAccounts(clientId).get(0)); - if (client.getString("sub_merchant_id") == null || client.getString("sub_merchant_id").equals("")) { - throw new BadRequestException("该商户未设置微信 Sub Merchant ID!"); - } JSONObject cardFlowInfo = clientCardFlowMapper.findClient(clientId); client.putAll(clientConfigService.find(client.getIntValue("client_id"))); Integer open_status_to = cardFlowInfo != null? cardFlowInfo.getIntValue("open_status") : null; @@ -1229,20 +1226,13 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid if (pass == 1) { createKycAuthStatus(manager, client); clientModifySupport.processClientConfigModify(new SwitchPermissionModify(manager, clientMoniker, "skip_clearing", false)); - if (client.getIntValue("source") == 4 || client.getIntValue("source") == 5) { - List accounts = clientAccountMapper.listAdminAccounts(client.getIntValue("client_id")); - JSONObject account = accounts.get(0); - //TODO 发送卡支付开通邮件 1.判断商户是否已开通跨境支付,若没有开通,init账号 -// sendInitEmail(client, account.getString("username"), "*****"); - saveClientAuditProcess(client.getIntValue("client_id"), open_status_to, 5, "合规通过", manager,2); - - clientModifySupport.processClientConfigModify(new SwitchPermissionModify(manager, clientMoniker, "skip_clearing", false)); -// gatewayMerchantApply.notifyOrgMerchantStatus(client); - } else { - //TODO 发送卡支付开通邮件 1.判断商户是否已开通跨境支付,若没有开通,init账号 -// initAdminUserAndSendEmail(manager, clientMoniker, client); - saveClientAuditProcess(client.getIntValue("client_id"), open_status_to, 5, "合规通过", manager,2); + List accounts = clientAccountMapper.listAdminAccounts(clientId); + if (accounts != null && accounts.size() > 0) { + sendInitEmail(client, accounts.get(0).getString("username"), "*******"); + }else { + initAdminUserAndSendEmail(manager, clientMoniker, client); } + saveClientAuditProcess(client.getIntValue("client_id"), open_status_to, 5, "合规通过", manager,2); } clientInfoCacheSupport.clearClientCache(client.getIntValue("client_id")); } @@ -1296,9 +1286,6 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } private void initAdminUserAndSendEmail(JSONObject manager, String clientMoniker, JSONObject client) { - if (StringUtils.isEmpty(client.getString("sub_merchant_id"))) { - throw new BadRequestException("Sub Merchant ID Can't be null "); - } String username = clientMoniker; boolean duplicated = true; String pwd = RandomStringUtils.random(8, true, true); From 4d4ad058b1b79324065e41dc3a92e453e2852cea Mon Sep 17 00:00:00 2001 From: dulingling Date: Tue, 28 Apr 2020 14:04:23 +0800 Subject: [PATCH 13/40] =?UTF-8?q?Upd:=E4=BF=A1=E7=94=A8=E5=8D=A1=E5=90=88?= =?UTF-8?q?=E8=A7=84=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mappers/system/ClientFilesMapper.java | 2 + .../mappers/system/ClientRateMapper.java | 2 + .../manage/merchants/core/ClientManager.java | 16 +- .../core/impls/ClientManagerImpl.java | 231 ++++++++-- .../web/PartnerManageController.java | 84 ++-- src/main/resources/application.yml | 11 + .../mappers/system/ClientFilesMapper.xml | 8 + .../mappers/system/ClientRateMapper.xml | 10 + .../templates/pdf/letter_of_offer.pdf | Bin 168390 -> 187904 bytes .../static/payment/partner/partner-manage.js | 137 +++++- .../partner/templates/partner_detail.html | 418 +++++++++--------- .../templates/partner_payment_info.html | 2 +- .../payment/partner/templates/partners.html | 4 +- 13 files changed, 642 insertions(+), 283 deletions(-) diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientFilesMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientFilesMapper.java index 1d036096e..d7169064e 100644 --- a/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientFilesMapper.java +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientFilesMapper.java @@ -52,6 +52,8 @@ public interface ClientFilesMapper { JSONObject getSourceAgreeFilesByClientId(@Param("client_id") int clientId); + JSONObject getSourceCardAgreeFilesByClientId(@Param("client_id") int clientId,@Param("file_name")String file_name); + void deleteByClientAndFileId(@Param("file_id") String file_id); void deleteAggreeByClientId(@Param("client_id") int file_id); diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientRateMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientRateMapper.java index 98ecbd655..a6972d809 100644 --- a/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientRateMapper.java +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientRateMapper.java @@ -53,6 +53,8 @@ public interface ClientRateMapper { JSONObject latestChannelCleanDays(@Param("rate_name")String rate_name, @Param("client_id")int client_id); + JSONObject latestCardChannelCleanDays(@Param("rate_name")String rate_name, @Param("client_id")int client_id); + JSONObject latestExpiryConfig(@Param("client_id")int client_id,@Param("rate_name") String rate_name); diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java index d95488795..46267d2f2 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java @@ -272,6 +272,8 @@ public interface ClientManager { JSONObject getSourceAgreeFiles(JSONObject manage, String clientMoniker); + JSONObject getSourceCardAgreeFiles(String clientMoniker, JSONObject manager, String fileName); + void deleteAuthFiles(String fileId); void deleteAuthFilesByAdmin(String fileId); @@ -300,6 +302,8 @@ public interface ClientManager { void commitToCompliance(String clientMoniker, JSONObject manager); + void commitToCardCompliance(String clientMoniker, JSONObject manager); + void commitToDoAgreeFile(String clientMoniker, JSONObject manager); /** @@ -387,6 +391,10 @@ public interface ClientManager { void getAggregateAgreeFile(String clientMoniker, JSONObject manager, boolean renewal) throws Exception; + void getAggregateCardAgreeFile(String clientMoniker, JSONObject manager, boolean renewal) throws Exception; + + void getAggregateCardPromotionaAgreeFile(String clientMoniker, JSONObject manager, boolean renewal,Date promotionalEffectiveDate,int promotionalPeriod) throws Exception; + void getNewAggregateAgreeFile(String clientMoniker, JSONObject manager, boolean renewal) throws Exception; void temporaryExportPdf(String clientMoniker, JSONObject manager, HttpServletResponse httpResponse) throws Exception; @@ -395,6 +403,8 @@ public interface ClientManager { void completeAgree(String clientMoniker, JSONObject manager); + void cardCompleteAgree(String clientMoniker, JSONObject manager); + void downloadComplianceZip(@PathVariable String clientMoniker, HttpServletResponse response) throws Exception; void downloadMWComplianceZip(@PathVariable String clientMoniker, HttpServletResponse response) throws Exception; @@ -596,10 +606,4 @@ public interface ClientManager { void selectBillCodeVersion(JSONObject manager, String clientMoniker, String version); - void exportLetterOfferPDF(String clientMoniker,HttpServletResponse response); - - void exportPromotionalOfferPDF(String moniker, String date, HttpServletResponse response); - - void exportTermsConditionsPDF(String clientMoniker,HttpServletResponse response); - } diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index f44f84a20..1a557da70 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -183,6 +183,11 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid @Resource private ClientIncrementalMapper clientIncrementalMapper; + @Value("${client_card.account_reserve}") + private String cardAccountReserve; + @Value("${client_card.annual_rate}") + private String cardAnnualRate; + @Value("${app.redis.prefix}") private String redisPrefix; private ApplicationEventPublisher publisher; @@ -340,6 +345,13 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid private static final String CLIENT_AGREE_FILE = "client_agree_file"; private static final String CLIENT_COMPANY_FILE = "client_company_file"; private static final String CLIENT_APPLY_FILE = "client_apply_file"; + + //卡支付合同文件 + private static final String LETTER_OF_OFFER_FILE="letter_of_offer_file"; + private static final String PROMOTIONAL_OFFER_FILE="promotional_offer_file"; + private static final String TERMS_AND_CONDITIONS_FILE="terms_and_conditions_file"; + + private static final List tags = new ArrayList<>(); private static final String KYC_UTILITY_BILL_FILE = "kyc_utility_bill_file"; @@ -1642,7 +1654,9 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid if (client == null) { throw new InvalidShortIdException(); } - clientModifySupport.processClientConfigModify(new SwitchPermissionModify(manager, clientMoniker, permissionKey, allow)); + JSONObject upayProfileInfo = sysClientUpayProfileMapper.findInfo(client.getInteger("client_id")); + upayProfileInfo.put(permissionKey,allow); + sysClientUpayProfileMapper.update(upayProfileInfo); } @Override @@ -3157,6 +3171,35 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } } + @Override + @Transactional + public void getAggregateCardAgreeFile(String clientMoniker, JSONObject manager, boolean renewal){ + JSONObject client = clientMapper.findClientByMoniker(clientMoniker); + if (client == null) { + throw new InvalidShortIdException(); + } + exportLetterOfferPDF(clientMoniker,manager); + exportTermsConditionsPDF(clientMoniker,manager); + + if (!renewal) { + JSONObject cardFlow = clientCardFlowMapper.findClient(client.getInteger("client_id")); + cardFlow.put("open_status",2); + clientCardFlowMapper.update(cardFlow); + } + if (manager != null) { + saveClientAuditProcess(client.getIntValue("client_id"), 1, 2, "Compliance合同制作中", manager,2); + } + } + @Override + @Transactional + public void getAggregateCardPromotionaAgreeFile(String clientMoniker, JSONObject manager, boolean renewal,Date promotionalEffectiveDate,int promotionalPeriod){ + JSONObject client = clientMapper.findClientByMoniker(clientMoniker); + if (client == null) { + throw new InvalidShortIdException(); + } + exportPromotionalOfferPDF(clientMoniker,manager,promotionalEffectiveDate,promotionalPeriod); + } + @Override public void getNewAggregateAgreeFile(String clientMoniker, JSONObject manager, boolean renewal) throws Exception { JSONObject client = getClientInfoByMoniker(clientMoniker); @@ -3376,6 +3419,24 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid sendCommissionWechatMessage(client); } + @Override + public void cardCompleteAgree(String clientMoniker, JSONObject manager) { + JSONObject client = getClientInfoByMoniker(clientMoniker); + if (client == null) { + throw new InvalidShortIdException(); + } + List existLeffterFiles = clientFilesMapper.findFileByClientAndType(client.getIntValue("client_id"), LETTER_OF_OFFER_FILE); + List existConditionsFiles = clientFilesMapper.findFileByClientAndType(client.getIntValue("client_id"), TERMS_AND_CONDITIONS_FILE); + if (CollectionUtils.isEmpty(existLeffterFiles) && CollectionUtils.isEmpty(existConditionsFiles)) { + throw new BadRequestException("The Agree File is not Complete!"); + } + JSONObject cardFlowInfo = clientCardFlowMapper.findClient(client.getInteger("client_id")); + cardFlowInfo.put("open_status", 3); + clientCardFlowMapper.update(cardFlowInfo); + saveClientAuditProcess(client.getIntValue("client_id"), 2, 3, "合同制作完成,等待BD处理", manager,2); + sendCardCommissionWechatMessage(client); + } + @Override public void downloadComplianceZip(String clientMoniker, HttpServletResponse response) throws Exception { JSONObject client = getClientInfoByMoniker(clientMoniker); @@ -3711,6 +3772,19 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid return sourceFile; } + @Override + public JSONObject getSourceCardAgreeFiles(String clientMoniker, JSONObject manager, String fileName){ + JSONObject client = getClientInfoByMoniker(clientMoniker); + if (client == null) { + throw new InvalidShortIdException(); + } + JSONObject sourceFile = clientFilesMapper.getSourceCardAgreeFilesByClientId(client.getIntValue("client_id"),fileName); + if (sourceFile != null) { + sourceFile.put(sourceFile.getString("file_name"), sourceFile.getString("file_value")); + } + return sourceFile; + } + @Override public JSONObject getAllAuthFiles(JSONObject manager, String clientMoniker) { JSONObject client = getClientInfoByMoniker(clientMoniker); @@ -4588,6 +4662,45 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } } + @Override + @Transactional + public void commitToCardCompliance(String clientMoniker, JSONObject manager) { + JSONObject client = getClientInfoByMoniker(clientMoniker); + if (client == null) { + throw new InvalidShortIdException(); + } + client.putAll(clientConfigService.find(client.getIntValue("client_id"))); + if (manager != null && ManagerRole.BD_USER.hasRole(manager.getIntValue("role"))) { + int bdOperatClientRole = clientBDMapper.checkBDPermission(client.getIntValue("client_id"), manager.getString("manager_id")); + if (bdOperatClientRole <= 0) { + throw new ForbiddenException(); + } + } + // 提交合规启用银行、费率验证 add by Tayl0r 2017/06/13 + JSONObject rate = merchantInfoProvider.clientCurrentRate(client.getIntValue("client_id"), new Date(), "rpaypmt_card"); + if (rate == null) { + throw new BadRequestException("The Partner's Rate is not config!"); + } + List clientFiles = clientFilesMapper.findClientFile(client.getIntValue("client_id")); + if (clientFiles == null || clientFiles.equals("")) { + throw new BadRequestException("The Compliance File Must Be Uploaded!"); + } + JSONObject account = getBankAccountByClientId(client.getIntValue("client_id")); + if (account == null) { + throw new BadRequestException("The Partner's Bank Account is not config!"); + } + JSONObject cardFlowInfo = clientCardFlowMapper.findClient(client.getInteger("client_id")); + int open_status_from = cardFlowInfo.getIntValue("open_status"); + cardFlowInfo.put("approve_time",new Date()); + cardFlowInfo.put("approve_result",4); + cardFlowInfo.put("open_status", 4); + clientCardFlowMapper.update(cardFlowInfo); + saveClientAuditProcess(client.getIntValue("client_id"), open_status_from, 4, "BD完成签字提交compliance审核", manager,2); + if (manager != null) { + sendCardCommissionWechatMessage(client); + } + } + private void saveClientAuditProcess(int client_id, Integer open_status_form, Integer open_status_to, String remark, JSONObject manager,int type) { JSONObject log = new JSONObject(); try { @@ -4640,6 +4753,11 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid client.putAll(clientConfigService.find(clientId)); beforeCommitToDoAgreeValid(client, manager); + JSONObject surCharge = merchantInfoProvider.clientCurrentRate(client.getIntValue("client_id"), new Date(), "rpaypmt_card"); + if (surCharge == null || surCharge.size() <= 0) { + throw new BadRequestException("The Partner's Rpaypmt Card Rate is not config!"); + } + JSONObject cardFlowInfo = clientCardFlowMapper.findClient(clientId); if(null != cardFlowInfo){ JSONObject cardFlow = new JSONObject(){{ @@ -5606,7 +5724,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid String wxopenid = compliance.getString("wx_openid"); try { MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); - TemplateMessage msg = initSendCommissionTemplate(wxopenid, paymentApi.getTemplateId("commission"), "BD申请制作卡支付合同" + client_moniker, + TemplateMessage msg = initSendCommissionTemplate(wxopenid, paymentApi.getTemplateId("commission"), "BD申请制作信用卡支付合同" + client_moniker, bd_user_name, "制作卡支付合同申请", "BD申请制作" + short_name + "的卡支付合同"); paymentApi.sendTemplateMessage(msg); } catch (WechatException e) { @@ -5624,7 +5742,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid if (wxopenid != null) { try { MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); - TemplateMessage msg = initSendCommissionTemplate(wxopenid, paymentApi.getTemplateId("commission"), client_moniker + "卡支付合同制作完成", + TemplateMessage msg = initSendCommissionTemplate(wxopenid, paymentApi.getTemplateId("commission"), client_moniker + "信用卡支付合同制作完成", "Compliance", "合规材料", "上传完整合规材料,商户:" + short_name); paymentApi.sendTemplateMessage(msg); } catch (WechatException e) { @@ -5647,7 +5765,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid String wxopenid = compliance.getString("wx_openid"); try { MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); - TemplateMessage msg = initSendCommissionTemplate(wxopenid, paymentApi.getTemplateId("commission"), client_moniker + "卡支付合规材料已提交", + TemplateMessage msg = initSendCommissionTemplate(wxopenid, paymentApi.getTemplateId("commission"), client_moniker + "信用卡卡支付合规材料已提交", bd_user_name, "审核材料", "已提交合规材料,等待审核"); paymentApi.sendTemplateMessage(msg); } catch (WechatException e) { @@ -7217,12 +7335,11 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid clientInfoCacheSupport.clearClientCache(client.getIntValue("client_id")); } - @Override - public void exportLetterOfferPDF(String clientMoniker, HttpServletResponse response) { + private void exportLetterOfferPDF(String clientMoniker,JSONObject manage) { JSONObject info = convertClientLetterOfferInfo(clientMoniker); String pdfPath = this.getClass().getClassLoader().getResource("").getPath() + "/templates/pdf/letter_of_offer.pdf"; String fileName = clientMoniker + "_Letter_of_Offer.pdf"; - publishExcelCardPDFFile(fileName, pdfPath, info, response); + publishExcelCardPDFFile(clientMoniker,manage,fileName, pdfPath, info,LETTER_OF_OFFER_FILE); } private JSONObject convertClientLetterOfferInfo(String clientMoniker) { @@ -7236,46 +7353,45 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } //获取数据源 int clientId = client.getInteger("client_id"); - JSONObject clientRate = clientRateMapper.latestChannelCleanDays("rpaypmt_card", clientId); + JSONObject clientRate = clientRateMapper.latestCardChannelCleanDays("rpaypmt_card", clientId); if (clientRate == null) { throw new BadRequestException("rpaypmt_card rate Not configured"); } JSONObject cardRate = clientRate.getJSONObject("ext_rates"); JSONObject bankAccountInfo = clientBankAccountMapper.clientBankAccounts(clientId).get(0); - + JSONObject upayProfileInfo = sysClientUpayProfileMapper.findInfo(clientId); //装在数据 JSONObject info = new JSONObject(); info.put("down_date", convertDateEnglish(new Date()));//下载文件日期 - info.put("bussiness_name", client.getString("business_name") + " ABN");//商圈类型 + info.put("bussiness_name", (client.containsKey("business_name")?client.getString("business_name"):client.getString("contact_person")) + " ABN");//商圈类型 info.put("partner_address", client.getString("address"));//商家店铺地址 info.put("partner_country", client.getString("country"));//国家 info.put("partner_state", client.getString("state"));//洲 info.put("partner_bussiness_name", client.getString("business_name"));//商户商用名称 info.put("clean_days", client.getInteger("clean_days"));//T+规则清算天数 - info.put("partner_industry_mcc", client.getInteger("industry"));//商户行业编码 - info.put("legal_bussiness", client.getString("contact_person") + " AS " + client.getString("business_name") + " ABN " + client.getString("abn"));//拼接规则:法人名 AS 商用名称 ABD 编码 - info.put("annual_rate", "0");//年费率 + info.put("partner_industry_mcc", upayProfileInfo.getString("mv_industy"));//信用卡注册商户行业编码 + info.put("legal_bussiness", client.getString("contact_person") + " AS " + (client.containsKey("business_name")?client.getString("business_name"):client.getString("contact_person")) + " ABN " + client.getString("abn"));//拼接规则:法人名 AS 商用名称 ABD 编码 + info.put("annual_rate",cardAnnualRate);//年费率 info.put("cost_per_transaction", clientRate.getString("transaction_fee"));//每次交易成本 info.put("domestic_fee", cardRate.getString("domestic_rate_value"));//国内服务费 info.put("international_fee", cardRate.getString("overseas_rate_value"));//国际服务费 - info.put("account_reserve", "1000");//账户储备金 + info.put("account_reserve", cardAccountReserve);//账户储备金 //银行账号信息 info.put("account_name", bankAccountInfo.getString("account_name"));// info.put("bsb", bankAccountInfo.getString("bsb_no")); info.put("account_no", bankAccountInfo.getString("account_no")); - info.put("card_acceptor_name", "xxxxxxxxxxxxx"); + info.put("card_acceptor_name", upayProfileInfo.getString("acceptor_name")); return info; } - @Override - public void exportPromotionalOfferPDF(String clientMoniker, String date, HttpServletResponse response) { - JSONObject info = convertPromotionalOfferInfo(clientMoniker, date); + private void exportPromotionalOfferPDF(String clientMoniker,JSONObject manager,Date promotionalEffectiveDate,int promotionalPeriod) { + JSONObject info = convertPromotionalOfferInfo(clientMoniker,convertDateEnglish(promotionalEffectiveDate),promotionalPeriod); String pdfPath = this.getClass().getClassLoader().getResource("").getPath() + "/templates/pdf/promotional_offer.pdf"; String fileName = clientMoniker + "_Promotional_Offer.pdf"; - publishExcelCardPDFFile(fileName, pdfPath, info, response); + publishExcelCardPDFFile(clientMoniker,manager,fileName, pdfPath, info,PROMOTIONAL_OFFER_FILE); } - private JSONObject convertPromotionalOfferInfo(String clientMoniker, String date) { + private JSONObject convertPromotionalOfferInfo(String clientMoniker,String promotionalEffectiveDate,int promotionalPeriod) { JSONObject client = getClientInfoByMoniker(clientMoniker); if (client == null) { throw new InvalidShortIdException(); @@ -7285,7 +7401,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid throw new BadRequestException("The merchant failed the audit!"); } int clientId = client.getInteger("client_id"); - JSONObject clientRate = clientRateMapper.latestChannelCleanDays("rpaypmt_card", clientId); + JSONObject clientRate = clientRateMapper.latestCardChannelCleanDays("rpaypmt_card", clientId); if (clientRate == null) { throw new BadRequestException("rpaypmt_card rate Not configured"); } @@ -7294,22 +7410,20 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid JSONObject info = new JSONObject(); info.put("down_date", convertDateEnglish(new Date()));//下载文件日期 - info.put("bussiness_name", client.getString("business_name") + " ABN");//商圈类型 + info.put("bussiness_name", (client.containsKey("business_name")?client.getString("business_name"):client.getString("contact_person")) + " ABN");//商圈类型 info.put("partner_address", client.getString("address"));//商家店铺地址 info.put("partner_country", client.getString("country"));//国家 info.put("partner_state", client.getString("state"));//洲 info.put("partner_bussiness_name", client.getString("business_name"));//商户商用名称 - info.put("letter_offer_sub_time", date); - info.put("legal_bussiness", client.getString("contact_person") + " AS " + client.getString("business_name") + " ABN " + client.getString("abn"));//拼接规则:法人名 AS 商用名称 ABD 编码 + info.put("legal_bussiness", client.getString("contact_person") + " AS " + (client.containsKey("business_name")?client.getString("business_name"):client.getString("contact_person")) + " ABN " + client.getString("abn"));//拼接规则:法人名 AS 商用名称 ABD 编码 info.put("domestic_fee", cardRate.getString("domestic_rate_value"));//国内服务费 info.put("international_fee", cardRate.getString("overseas_rate_value"));//国际服务费 - info.put("promotional_effective_date", "xxxxxxxxx"); - info.put("promotional_period", "xxxxxxxxx"); + info.put("promotional_effective_date", promotionalEffectiveDate); + info.put("promotional_period", promotionalPeriod); return info; } - @Override - public void exportTermsConditionsPDF(String clientMoniker, HttpServletResponse response) { + private void exportTermsConditionsPDF(String clientMoniker,JSONObject manage) { JSONObject client = getClientInfoByMoniker(clientMoniker); if (client == null) { throw new InvalidShortIdException(); @@ -7319,24 +7433,26 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } String pdfPath = this.getClass().getClassLoader().getResource("").getPath() + "/templates/pdf/terms_and_conditions.pdf"; String fileName = clientMoniker + "_Terms_And_Conditions.pdf"; - publishExcelCardPDFFile(fileName, pdfPath, new JSONObject(), response); + publishExcelCardPDFFile(clientMoniker,manage,fileName, pdfPath, new JSONObject(),TERMS_AND_CONDITIONS_FILE); } - private void publishExcelCardPDFFile(String fileName, String pdfPath, JSONObject info, HttpServletResponse response) { - response.setContentType("application/pdf"); - response.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ".pdf"); + private void publishExcelCardPDFFile(String clientMoniker,JSONObject manager, String fileName, String pdfPath, JSONObject info, String fileLabel) { try { - OutputStream outs = response.getOutputStream(); PdfUtils pdu = new PdfUtils(); pdu.setTemplatePdfPath(pdfPath); pdu.setPdfTemplate(info); - File file = new File(fileName); - ByteArrayOutputStream bos = pdu.templetPdfBos(file, "", ""); - outs.write(bos.toByteArray(), 0, bos.toByteArray().length); - outs.flush(); - outs.close(); - } catch (IOException e) { - e.printStackTrace(); + try { + File file = new File(fileName); + ByteArrayOutputStream bos = pdu.templetPdfBos(file); + InputStream stream = new ByteArrayInputStream(bos.toByteArray()); + JSONObject fileRes = attachmentClient.uploadFile(stream, fileName, false); + if (fileRes != null) { + importCardAgreeFile(clientMoniker, manager, fileRes.getString("url"), fileLabel); + } + stream.close(); + } catch (Exception e) { + logger.error("合同制作出现问题:", e); + } } catch (Exception e) { e.printStackTrace(); } @@ -7352,6 +7468,41 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid return day + " " + months[month] + " " + year; } + private void importCardAgreeFile(String clientMoniker, JSONObject manager, String sourceFile, String fileLabel) { + JSONObject client = getClientInfoByMoniker(clientMoniker); + if (client == null) { + throw new InvalidShortIdException(); + } + if (sourceFile != null) { + List existFiles = clientFilesMapper.findFileByClientAndType(client.getIntValue("client_id"), fileLabel); + JSONObject existFile = null; + if (!CollectionUtils.isEmpty(existFiles)) { + existFile = existFiles.get(0); + } + Date now = new Date(); + JSONObject file = new JSONObject(); + file.put("file_name", fileLabel); + file.put("file_value", sourceFile); + file.put("client_id", client.getIntValue("client_id")); + file.put("last_update_date", now); + file.put("status", 1); + file.put("is_valid", 1); + if (manager == null) { + file.put("last_update_by", "System Import"); + } else { + file.put("last_update_by", manager.getString("display_name")); + } + JSONObject contract = clientsContractMapper.findByClientId(client.getIntValue("client_id")); + if (contract == null || now.compareTo(contract.getDate("expiry_date")) > 0 || !contract.getBoolean("has_sign") || existFile == null + || existFile.isEmpty()) { + clientFilesMapper.save(file); + } else { + file.put("file_id", existFile.getString("file_id")); + clientFilesMapper.update(file); + } + } + } + public void saveLegalAndMarketingInfo(JSONObject partner) { JSONObject representativeInfo = new JSONObject(); representativeInfo.put("client_id", partner.getIntValue("client_id")); diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java b/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java index 8fc8d8cce..d89fc146a 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java @@ -595,6 +595,17 @@ public class PartnerManageController { return clientManager.getSourceAgreeFiles(manager, clientMoniker); } + /** + * 下载商户卡支付合规文件 + * + * @param clientMoniker + */ + @ManagerMapping(value = "/{clientMoniker}/file/source_card_agree_file", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR, ManagerRole.BD_USER, ManagerRole.SERVANT}) + public JSONObject getSourceCardAgreeAuthFiles(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, + @RequestParam("fileName") String fileName){ + return clientManager.getSourceCardAgreeFiles(clientMoniker,manager,fileName); + } + @ManagerMapping(value = "/auth_file/{fileId}/delete", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR, ManagerRole.BD_USER}) public void deleteAuthFiles(@PathVariable String fileId, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { clientManager.deleteAuthFilesByAdmin(fileId); @@ -634,12 +645,21 @@ public class PartnerManageController { clientManager.commitToCompliance(clientMoniker, manager); } + /** + * 提交资料,BD提交卡支付最终审核 + * @param clientMoniker + * @param manager + */ + @ManagerMapping(value = "/{clientMoniker}/to_card_compliance", method = RequestMethod.PUT, role = {ManagerRole.ADMIN, ManagerRole.BD_USER}) + public void commitToCardCompliance(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + clientManager.commitToCardCompliance(clientMoniker, manager); + } + @ManagerMapping(value = "/{clientMoniker}/make_agree_file", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.BD_USER}) public void commitToDoAgreeFile(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { clientManager.commitToDoAgreeFile(clientMoniker, manager); } - //TODO BD提交申请卡合规 /** * 提交资料,申请卡支付 * @param clientMoniker @@ -665,6 +685,29 @@ public class PartnerManageController { clientManager.getAggregateAgreeFile(clientMoniker, manager, false); } + /** + * 制作卡支付合同 + * @param clientMoniker + * @param manager + * @throws Exception + */ + @ManagerMapping(value = "/{clientMoniker}/export/aggregate/card_agree_pdf", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.DIRECTOR, ManagerRole.OPERATOR}) + public void exportAggregateCardAgreeFile(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) throws Exception { + clientManager.getAggregateCardAgreeFile(clientMoniker, manager, false); + } + + /** + * 制作促销合同 + * @param clientMoniker + * @param manager + * @throws Exception + */ + @ManagerMapping(value = "/{clientMoniker}/export/aggregate/card_promotiona_agree_pdf", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.DIRECTOR, ManagerRole.OPERATOR}) + public void exportAggregateCardPromotionaAgreeFile(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, + @RequestParam("date") Date promotionalEffectiveDate,@RequestParam("period") int promotionalPeriod) throws Exception { + clientManager.getAggregateCardPromotionaAgreeFile(clientMoniker, manager, false,promotionalEffectiveDate,promotionalPeriod); + } + @ManagerMapping(value = "/{clientMoniker}/temp/export/pdf", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.BD_USER, ManagerRole.DIRECTOR, ManagerRole.OPERATOR}) public void temporaryExportPDF(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, HttpServletResponse httpResponse) throws Exception { clientManager.temporaryExportPdf(clientMoniker, manager, httpResponse); @@ -680,6 +723,16 @@ public class PartnerManageController { clientManager.completeAgree(clientMoniker, manager); } + /** + * 信用卡合同生成完毕通知BD + * @param clientMoniker + * @param manager + */ + @ManagerMapping(value = "/{clientMoniker}/notify/cardCompleteAgree", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR}) + public void cardCompleteAgree(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + clientManager.cardCompleteAgree(clientMoniker, manager); + } + @ManagerMapping(value = "/{clientMoniker}/download/complianceAsZIP", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR}) public void downloadComplianceZip(@PathVariable String clientMoniker, HttpServletResponse response) throws Exception { clientManager.downloadComplianceZip(clientMoniker, response); @@ -961,33 +1014,4 @@ public class PartnerManageController { clientManager.switchPermission(manager, clientMoniker, "enable_international_card", pass.getBooleanValue("allow")); } - /** - * 下载商户Letter of Offer pdf文件 - * - * @param clientMoniker - */ - @ManagerMapping(value = "/{clientMoniker}/export/letter_of_offer_pdf", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR}) - public void exportLetterOfferPDF(@PathVariable String clientMoniker,HttpServletResponse response){ - clientManager.exportLetterOfferPDF(clientMoniker,response); - } - - /** - * 下载商户Promotional Offer pdf文件 - * - * @param clientMoniker - */ - @ManagerMapping(value = "/{clientMoniker}/export/promotional_offer_pdf", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR}) - public void exportPromotionalOfferPDF(@PathVariable String clientMoniker, @RequestParam("date")String date, HttpServletResponse response){ - clientManager.exportPromotionalOfferPDF(clientMoniker,date,response); - } - - /** - * 下载Terms Conditions pdf文件 - * - * @param clientMoniker - */ - @ManagerMapping(value = "/{clientMoniker}/export/terms_conditions_pdf", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR}) - public void exportTermsConditionsPDF(@PathVariable String clientMoniker,HttpServletResponse response){ - clientManager.exportTermsConditionsPDF(clientMoniker,response); - } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 0bde059ef..b57b9f590 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -68,6 +68,11 @@ app: tax: type: GST +client_card: + account_reserve: 1000 + annual_rate: 0 + + apple: message: apns: @@ -153,6 +158,12 @@ spring: port: 6379 thymeleaf: mode: HTML +logging: + level: + au: + com: + royalpay: + payment: debug diff --git a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientFilesMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientFilesMapper.xml index 2fec0585a..e2914bf54 100644 --- a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientFilesMapper.xml +++ b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientFilesMapper.xml @@ -19,6 +19,14 @@ and file_name = 'source_agree_file' order by last_update_date desc limit 1 + + + + +
    ' + + ' 请输入活动周期: '); + var choises = [{label: '取消', className: 'btn-danger', key: '2', dismiss: true}, + {label: '确认提交', className: 'btn-success', key: '1'}]; + var content = ''; + $scope.showCardPromotionaBg = true; + commonDialog.confirm({ + title: title, + content: content, + choises: choises, + contentHtml: contentHtml + }).then(function (res) { + if(params != null){ + $http.get('/sys/partners/' + $scope.partner.client_moniker + '/export/aggregate/card_promotiona_agree_pdf').then(function () { + commonDialog.alert({ + title: 'Success', + content: 'Agreement File Generate Succeed! Please notify BD!', + type: 'success' + }); + $scope.showCardPromotionaBg = false; + $state.reload(); + }, function (resp) { + $scope.showCardPromotionaBg = false; + $state.reload(); + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); + }); + } + }); + + } + $scope.Export = function () { var url = '/dev/' + $scope.partner.client_moniker + '/export/aggregate/agreepdf'; return url; @@ -681,6 +750,33 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter } } }; + + $scope.uploadCardAgreeFile = function (file) { + if (file != null) { + if (file.size > 2 * 1024 * 1024) { + commonDialog.alert({title: 'Error', content: '文件大小不能超过2MB,请压缩后重试', type: 'error'}) + } else { + Upload.upload({ + url: '/attachment/files', + data: {file: file} + }).then(function (resp) { + $scope.agree_file_import = resp.data.url; + $http.put('/sys/partners/' + $scope.partner.client_moniker + '/import/agreepdf', {source_agree_file: $scope.agree_file_import}).then(function () { + commonDialog.alert({ + title: 'Success', + content: 'Succeed Imported! Please notify BD', + type: 'success' + }); + $state.reload(); + }, function (resp) { + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); + }) + }, function (resp) { + commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}) + }) + } + } + }; $scope.notifyBD = function () { $http.get('/sys/partners/' + $scope.partner.client_moniker + '/notify/completeAgree').then(function () { commonDialog.alert({ @@ -694,6 +790,19 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter }); }; + $scope.cardNotifyBD = function () { + $http.get('/sys/partners/' + $scope.partner.client_moniker + '/notify/cardCompleteAgree').then(function () { + commonDialog.alert({ + title: 'Success', + content: 'Notify BD Successed!.', + type: 'success' + }); + $state.reload(); + }, function (resp) { + commonDialog.alert({title: 'Upload Failed', content: resp.data.message, type: 'error'}); + }); + }; + $scope.downTempPdf = function () { var url = '/sys/partners/' + $scope.partner.client_moniker + '/temp/export/pdf'; return url; @@ -779,6 +888,30 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter } }) }; + + $scope.commitToCardCompliance = function(){ + commonDialog.confirm({ + title: 'Commit to Compliance', + content: 'Are you sure to commit ' + $scope.partner.company_name + ' to compliance?', + choises: [ + {label: 'Submit', className: 'btn-success', key: 1}, + {label: 'Cancel', className: 'btn-warning', key: 0, dismiss: true} + ] + }).then(function (choice) { + if (choice == 1) { + $http.put('/sys/partners/' + $scope.partner.client_moniker + '/to_card_compliance', {}).then(function () { + commonDialog.alert({ + title: 'Success', + content: 'Commit to Compliance successfully', + type: 'success' + }); + $state.reload(); + }, function (resp) { + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); + }) + } + }) + } $scope.apply2makeAgreeFile = function () { $http.get('/sys/partners/' + $scope.partner.client_moniker + '/make_agree_file').then(function () { commonDialog.alert({ diff --git a/src/main/ui/static/payment/partner/templates/partner_detail.html b/src/main/ui/static/payment/partner/templates/partner_detail.html index c043063a9..7c83452cd 100644 --- a/src/main/ui/static/payment/partner/templates/partner_detail.html +++ b/src/main/ui/static/payment/partner/templates/partner_detail.html @@ -60,188 +60,178 @@
    -
    -
    -

    Compliance (Refused - :{{partner.refuse_remark}}) - (The Partner Using Green Channel Now!) - 【目前状态】- - - (自助申请)资料完善中 - (自助申请)已开通 - (自助申请)快速开通等待提交合规材料 - (自助申请)待审核(材料已提交) - - - 资料完善中 - 待审核(合同制作中) - 合同制作完成 - BD处理中 - 待审核(合规文件已提交) - 通过 - 不通过 - 绿色通道申请中 - - (已禁用) -

    - -
    -
    -
    - - - - 制作临时合同 - - 制作全支付合同 - - 上传合同 (通用合同请选择制作合同,非通用合同模板请人工制作合同后上传) -
    -
    - - -
    -
    - -
    - 下载合同 - - - Notify BD - -
    -
    - - - - - - -
    - -
    - -
    -
    - - -
    - - -
    -
    -
    -
    -
    -
    -
    -
    -

    - - RP Operation - (Refused - :{{partner.refuse_remark}} - )(The Partner Using Green Channel Now!) - 【目前状态】- - 资料完善中 - 待审核(合同制作中) - 合同制作完成 - BD处理中 - 待审核(合规文件已提交) - 通过 - 不通过 - 绿色通道申请中 -

    -
    -
    - - 下载合同 -
    - -
    -
    - -
    -
    - -
    -
    -
    - - - - - - -
    - -
    - -
    -
    - - -
    - - -
    -
    -
    -
    -
    -
    -
    -
    -

    Solved

    -
    -
    -
    Make sure you have send the email to client.
    -
    - -
    -
    -
    +
    +
    +

    Compliance (Refused + :{{partner.refuse_remark}}) + (The Partner Using Green Channel Now!) + 【目前状态】- + + (自助申请)资料完善中 + (自助申请)已开通 + (自助申请)快速开通等待提交合规材料 + (自助申请)待审核(材料已提交) + + + 资料完善中 + 待审核(合同制作中) + 合同制作完成 + BD处理中 + 待审核(合规文件已提交) + 通过 + 不通过 + 绿色通道申请中 + + (已禁用) +

    + +
    +
    +
    + + + + 制作临时合同 + + 制作全支付合同 + + 上传合同 (通用合同请选择制作合同,非通用合同模板请人工制作合同后上传) +
    +
    + + + +
    +
    + +
    + 下载合同 + + + Notify BD + +
    +
    + + + + + + +
    + +
    + +
    +
    + + +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +

    + + Operation + (Refused + :{{partner.refuse_remark}} + )(The Partner Using Green Channel Now!) + 【目前状态】- + 资料完善中 + 待审核(合同制作中) + 合同制作完成 + BD处理中 + 待审核(合规文件已提交) + 通过 + 不通过 + 绿色通道申请中 +

    +
    +
    + + 下载合同 +
    + +
    +
    + +
    +
    + +
    +
    +
    + + + + + + +
    + +
    + +
    +
    + + +
    + + +
    +
    +
    +
    +
    +
    @@ -277,29 +267,35 @@
    -
    +
    - - 制作全支付合同 - - 上传合同 (通用合同请选择制作合同,非通用合同模板请人工制作合同后上传) + + 制作卡支付合同 + + 制作促销合同
    +
    -
    - 下载合同 + 下载Letter Of Offer合同 + 下载Terms And Conditions合同 + 下载Promotional Offer合同 + ng-click="cardNotifyBD()"> Notify BD
    @@ -329,9 +325,9 @@
    + ng-class="{'box-warning':partner.card_flow_info.approve_result!=5,'box-danger':partner.card_flow_info.approve_result==5}">
    -

    Card Payment Operation +

    Operation (Refused :{{partner.card_flow_info.refuse_remark}} )

    - - 下载合同 + 下载Letter Of Offer合同 + 下载Terms And Conditions合同 + 下载Promotional Offer合同
    -
    +
    - -
    + + +

    Solved

    @@ -1293,7 +1307,7 @@
    diff --git a/src/main/ui/static/payment/partner/templates/partner_payment_info.html b/src/main/ui/static/payment/partner/templates/partner_payment_info.html index aff94a22e..6d9aff34c 100644 --- a/src/main/ui/static/payment/partner/templates/partner_payment_info.html +++ b/src/main/ui/static/payment/partner/templates/partner_payment_info.html @@ -490,7 +490,7 @@
    -
    +
    Card Payment Config
    diff --git a/src/main/ui/static/payment/partner/templates/partners.html b/src/main/ui/static/payment/partner/templates/partners.html index c6ca05969..cd0e03ebc 100644 --- a/src/main/ui/static/payment/partner/templates/partners.html +++ b/src/main/ui/static/payment/partner/templates/partners.html @@ -503,7 +503,7 @@ 等待合规
    - 等待BD上传材料审核 + 资料完善中
    @@ -511,7 +511,7 @@ 资料完善中 (自助开通)资料完善中 不通过({{partner.card_approve_flow_info.approve_time}}) - 申请打回({{partner.card_approve_flow_info.refuse_remark|limitTo:15}}) + 申请打回({{partner.card_approve_flow_info.refuse_remark|limitTo:15}}) 等待合规 合同制作完成 等待BD上传材料审核 From de5f731309c665602a17a35ef3d20df107719e02 Mon Sep 17 00:00:00 2001 From: luoyang Date: Tue, 28 Apr 2020 14:24:33 +0800 Subject: [PATCH 14/40] =?UTF-8?q?fix=20upay=E8=A1=A5=E5=85=85=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E8=A1=A8=E5=A2=9E=E5=8A=A0=E5=90=88=E8=A7=84=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mappers/system/ClientCardFlowMapper.java | 31 ---- .../core/impls/ClientManagerImpl.java | 146 +++++++++--------- .../manage/mappers/system/ClientMapper.xml | 12 +- .../payment/partner/templates/partners.html | 22 +-- 4 files changed, 94 insertions(+), 117 deletions(-) delete mode 100644 src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientCardFlowMapper.java diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientCardFlowMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientCardFlowMapper.java deleted file mode 100644 index 485ef152c..000000000 --- a/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientCardFlowMapper.java +++ /dev/null @@ -1,31 +0,0 @@ -package au.com.royalpay.payment.manage.mappers.system; - -import com.alibaba.fastjson.JSONObject; -import com.github.miemiedev.mybatis.paginator.domain.PageBounds; -import com.github.miemiedev.mybatis.paginator.domain.PageList; -import com.yixsoft.support.mybatis.autosql.annotations.AdvanceSelect; -import com.yixsoft.support.mybatis.autosql.annotations.AutoMapper; -import com.yixsoft.support.mybatis.autosql.annotations.AutoSql; -import com.yixsoft.support.mybatis.autosql.annotations.SqlType; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; -import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator; - -import java.util.Date; -import java.util.List; - -/** - * Created by dulingling on 2020-04-26. - */ -@AutoMapper(tablename = "sys_clients_card_flow", pkName = "client_id", keyGenerator = Jdbc3KeyGenerator.class) -public interface ClientCardFlowMapper { - @AutoSql(SqlType.SELECT) - JSONObject findClient(@Param("client_id") int clientId); - - @AutoSql(SqlType.INSERT) - void save(JSONObject partner); - - @AutoSql(SqlType.UPDATE) - int update(JSONObject partner); - -} diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index 1a557da70..b6a5dba47 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -333,8 +333,6 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid private RPayMerchantMapper rPayMerchantMapper; @Resource private SysClientUpayProfileMapper sysClientUpayProfileMapper; - @Resource - private ClientCardFlowMapper clientCardFlowMapper; @Resource @@ -519,12 +517,6 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid client.put("audit_card_logs", audit_card_logs); } - //插入卡支付审核状态 - JSONObject cardFlowInfo = clientCardFlowMapper.findClient(client.getInteger("client_id")); - if(null != cardFlowInfo){ - client.put("card_flow_info",cardFlowInfo); - } - //HF支付链接二维码 if (client.getString("hf_pay_url") != null) { String hfQrcodeUrl = PlatformEnvironment.getEnv().concatUrl("/api/v1.0/hf_gateway/partners/" + client.getString("client_moniker") + "/jump/app"); @@ -598,10 +590,6 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid partner.put("expiry_time", DateUtils.addDays(partner.getDate("approve_time"), authDays)); partner.put("pass_timeout", DateUtils.addDays(partner.getDate("approve_time"), authDays).compareTo(new Date()) < 0); } - JSONObject cardFlowInfo = clientCardFlowMapper.findClient(partner.getInteger("client_id")); - if(null != cardFlowInfo){ - partner.put("card_approve_flow_info",cardFlowInfo); - } } return PageListUtils.buildPageListResult(partners); } @@ -1200,7 +1188,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid if (client.getIntValue("source") == 4 || client.getIntValue("source") == 5) { List accounts = clientAccountMapper.listAdminAccounts(client.getIntValue("client_id")); JSONObject account = accounts.get(0); - sendInitEmail(client, account.getString("username"), "*****"); + sendInitEmail(client, account.getString("username"), "*****", false); // sendInitEmail(manager, client, account.getString("username"), "*****"); saveClientAuditProcess(client.getIntValue("client_id"), open_status, 5, "合规通过", manager,1); clientModifySupport.processClientConfigModify(new SwitchPermissionModify(manager, clientMoniker, "skip_clearing", false)); @@ -1211,7 +1199,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid logger.info("PASS 绿色通道:" + clientMoniker); saveClientAuditProcess(client.getIntValue("client_id"), open_status, 5, "合规通过", manager,1); } else { - initAdminUserAndSendEmail(manager, clientMoniker, client); + initAdminUserAndSendEmail(manager, clientMoniker, client, false); saveClientAuditProcess(client.getIntValue("client_id"), open_status, 5, "合规通过", manager,1); } } @@ -1228,21 +1216,21 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid int clientId = client.getIntValue("client_id"); isRiskyMerchant(client, clientBankAccountMapper.clientBankAccounts(clientId).get(0)); - JSONObject cardFlowInfo = clientCardFlowMapper.findClient(clientId); + JSONObject cardFlowInfo = sysClientUpayProfileMapper.findInfo(clientId); client.putAll(clientConfigService.find(client.getIntValue("client_id"))); - Integer open_status_to = cardFlowInfo != null? cardFlowInfo.getIntValue("open_status") : null; - cardFlowInfo.put("open_status",5); - cardFlowInfo.put("approve_result",1); - clientCardFlowMapper.update(cardFlowInfo); + Integer open_status_to = cardFlowInfo != null? cardFlowInfo.getIntValue("upay_open_status") : null; + cardFlowInfo.put("upay_open_status",5); + cardFlowInfo.put("upay_approve_result",1); + sysClientUpayProfileMapper.update(cardFlowInfo); sendCardCommissionWechatMessage(client);// wxMessage if (pass == 1) { createKycAuthStatus(manager, client); clientModifySupport.processClientConfigModify(new SwitchPermissionModify(manager, clientMoniker, "skip_clearing", false)); List accounts = clientAccountMapper.listAdminAccounts(clientId); if (accounts != null && accounts.size() > 0) { - sendInitEmail(client, accounts.get(0).getString("username"), "*******"); + sendInitEmail(client, accounts.get(0).getString("username"), "*******", true); }else { - initAdminUserAndSendEmail(manager, clientMoniker, client); + initAdminUserAndSendEmail(manager, clientMoniker, client, true); } saveClientAuditProcess(client.getIntValue("client_id"), open_status_to, 5, "合规通过", manager,2); } @@ -1294,10 +1282,10 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid clientModifySupport.processClientModify(new GreenChannelModify(manager, clientMoniker, manager.getString("manager_id"))); saveClientAuditProcess(client.getIntValue("client_id"), 10, 1, "绿色通道申请通过", manager,1); sendCommissionWechatMessage(client); - initAdminUserAndSendEmail(manager, clientMoniker, client); + initAdminUserAndSendEmail(manager, clientMoniker, client, false); } - private void initAdminUserAndSendEmail(JSONObject manager, String clientMoniker, JSONObject client) { + private void initAdminUserAndSendEmail(JSONObject manager, String clientMoniker, JSONObject client,boolean isUpayEmail) { String username = clientMoniker; boolean duplicated = true; String pwd = RandomStringUtils.random(8, true, true); @@ -1314,7 +1302,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid username += "0"; } } - sendInitEmail(client, username.toLowerCase(), pwd); + sendInitEmail(client, username.toLowerCase(), pwd, isUpayEmail); // sendInitEmail(manager, client, username, pwd); } @@ -1340,16 +1328,16 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid if (client.getIntValue("source") == 4) { JSONObject account = accounts.get(0); // sendInitEmail(manager, client, account.getString("username"), "*****"); - sendInitEmail(client, account.getString("username"), "*****"); + sendInitEmail(client, account.getString("username"), "*****", false); } else { if (accounts.size() == 0) { - initAdminUserAndSendEmail(manager, clientMoniker, client); + initAdminUserAndSendEmail(manager, clientMoniker, client, false); } else { JSONObject account = accounts.get(0); String pwd = RandomStringUtils.random(8, true, true); resetAccountPwd(manager, clientMoniker, account.getString("account_id"), pwd); // sendInitEmail(manager, client, account.getString("username"), pwd); - sendInitEmail(client, account.getString("username"), pwd); + sendInitEmail(client, account.getString("username"), pwd, false); } } } @@ -1421,7 +1409,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid }.start(); } - public void sendInitEmail(final JSONObject client, String username, String pwd) { + public void sendInitEmail(final JSONObject client, String username, String pwd,boolean isUpayAuditPass) { logger.debug("sending email after comply"); JSONObject model = new JSONObject(); model.put("username", username); @@ -1471,16 +1459,30 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid mailService.sendEmail("Your RoyalPay Cross-border Payment has been set up", emails.isEmpty() ? "" : StringUtils.join(emails, ","), "", contentBd); JSONObject clientUpdate = new JSONObject(); - clientUpdate.put("client_id", client.getIntValue("client_id")); - clientUpdate.put("approve_email_send", 3); - clientUpdate.put("approve_email_id", emailId); - clientMapper.update(clientUpdate); + if (isUpayAuditPass) { + clientUpdate.put("client_id", client.getIntValue("client_id")); + clientUpdate.put("upay_approve_email_send", 3); + clientUpdate.put("upay_approve_email_id", emailId); + sysClientUpayProfileMapper.update(clientUpdate); + }else { + clientUpdate.put("client_id", client.getIntValue("client_id")); + clientUpdate.put("approve_email_send", 3); + clientUpdate.put("approve_email_id", emailId); + clientMapper.update(clientUpdate); + } } catch (Exception e) { JSONObject clientUpdate = new JSONObject(); - clientUpdate.put("client_id", client.getIntValue("client_id")); - clientUpdate.put("approve_email_send", 0); - clientUpdate.put("approve_email_id", null); - clientMapper.update(clientUpdate); + if (isUpayAuditPass) { + clientUpdate.put("client_id", client.getIntValue("client_id")); + clientUpdate.put("upay_approve_email_send", 0); + clientUpdate.put("upay_approve_email_id", null); + sysClientUpayProfileMapper.update(clientUpdate); + }else { + clientUpdate.put("client_id", client.getIntValue("client_id")); + clientUpdate.put("approve_email_send", 0); + clientUpdate.put("approve_email_id", null); + clientMapper.update(clientUpdate); + } throw new EmailException("Email Sending Failed", e); } } @@ -3182,9 +3184,9 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid exportTermsConditionsPDF(clientMoniker,manager); if (!renewal) { - JSONObject cardFlow = clientCardFlowMapper.findClient(client.getInteger("client_id")); - cardFlow.put("open_status",2); - clientCardFlowMapper.update(cardFlow); + JSONObject cardFlow = sysClientUpayProfileMapper.findInfo(client.getInteger("client_id")); + cardFlow.put("upay_open_status",2); + sysClientUpayProfileMapper.update(cardFlow); } if (manager != null) { saveClientAuditProcess(client.getIntValue("client_id"), 1, 2, "Compliance合同制作中", manager,2); @@ -3430,9 +3432,9 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid if (CollectionUtils.isEmpty(existLeffterFiles) && CollectionUtils.isEmpty(existConditionsFiles)) { throw new BadRequestException("The Agree File is not Complete!"); } - JSONObject cardFlowInfo = clientCardFlowMapper.findClient(client.getInteger("client_id")); - cardFlowInfo.put("open_status", 3); - clientCardFlowMapper.update(cardFlowInfo); + JSONObject cardFlowInfo = sysClientUpayProfileMapper.findInfo(client.getInteger("client_id")); + cardFlowInfo.put("upay_open_status", 3); + sysClientUpayProfileMapper.update(cardFlowInfo); saveClientAuditProcess(client.getIntValue("client_id"), 2, 3, "合同制作完成,等待BD处理", manager,2); sendCardCommissionWechatMessage(client); } @@ -4683,18 +4685,18 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } List clientFiles = clientFilesMapper.findClientFile(client.getIntValue("client_id")); if (clientFiles == null || clientFiles.equals("")) { - throw new BadRequestException("The Compliance File Must Be Uploaded!"); + throw new BadRequestException("The Compliance File Must Be Uploaded!"); } JSONObject account = getBankAccountByClientId(client.getIntValue("client_id")); if (account == null) { throw new BadRequestException("The Partner's Bank Account is not config!"); } - JSONObject cardFlowInfo = clientCardFlowMapper.findClient(client.getInteger("client_id")); - int open_status_from = cardFlowInfo.getIntValue("open_status"); - cardFlowInfo.put("approve_time",new Date()); - cardFlowInfo.put("approve_result",4); - cardFlowInfo.put("open_status", 4); - clientCardFlowMapper.update(cardFlowInfo); + JSONObject cardFlowInfo = sysClientUpayProfileMapper.findInfo(client.getInteger("client_id")); + int open_status_from = cardFlowInfo.getIntValue("upay_open_status"); + cardFlowInfo.put("upay_approve_time",new Date()); + cardFlowInfo.put("upay_approve_result",4); + cardFlowInfo.put("upay_open_status", 4); + sysClientUpayProfileMapper.update(cardFlowInfo); saveClientAuditProcess(client.getIntValue("client_id"), open_status_from, 4, "BD完成签字提交compliance审核", manager,2); if (manager != null) { sendCardCommissionWechatMessage(client); @@ -4758,23 +4760,23 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid throw new BadRequestException("The Partner's Rpaypmt Card Rate is not config!"); } - JSONObject cardFlowInfo = clientCardFlowMapper.findClient(clientId); + JSONObject cardFlowInfo = sysClientUpayProfileMapper.findInfo(clientId); if(null != cardFlowInfo){ JSONObject cardFlow = new JSONObject(){{ put("client_id",clientId); - put("approve_result",4); - put("open_status",1); - put("approve_time",new Date()); + put("upay_approve_result",4); + put("upay_open_status",1); + put("upay_approve_time",new Date()); }}; - clientCardFlowMapper.update(cardFlow); + sysClientUpayProfileMapper.save(cardFlow); }else{ JSONObject cardFlow = new JSONObject(){{ put("client_id",clientId); - put("open_status",1); - put("approve_result",4); - put("approve_time",new Date()); + put("upay_open_status",1); + put("upay_approve_result",4); + put("upay_approve_time",new Date()); }}; - clientCardFlowMapper.save(cardFlow); + sysClientUpayProfileMapper.save(cardFlow); } saveClientAuditProcess(client.getIntValue("client_id"), null, 1, "提交Compliance制作合同", manager,2); @@ -5150,26 +5152,26 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid throw new InvalidShortIdException(); } Integer clientId = client.getInteger("client_id"); - JSONObject cardFlowInfo = clientCardFlowMapper.findClient(clientId); + JSONObject cardFlowInfo = sysClientUpayProfileMapper.findInfo(clientId); Integer open_status = null; if(null != cardFlowInfo){ - open_status = cardFlowInfo.getIntValue("open_status"); + open_status = cardFlowInfo.getIntValue("upay_open_status"); if (open_status == 1) { - cardFlowInfo.put("open_status",null); + cardFlowInfo.put("upay_open_status",null); } else { - cardFlowInfo.put("open_status",open_status - 1); + cardFlowInfo.put("upay_open_status",open_status - 1); } - if ( cardFlowInfo.getIntValue("approve_result") == 4 || client.getIntValue("source") == 4) { - cardFlowInfo.put("approve_result",5); + if ( cardFlowInfo.getIntValue("upay_approve_result") == 4 || client.getIntValue("source") == 4) { + cardFlowInfo.put("upay_approve_result",5); } if (refuse_remark != null && !refuse_remark.isEmpty()) { - cardFlowInfo.put("refuse_remark",refuse_remark); + cardFlowInfo.put("upay_refuse_remark",refuse_remark); } }else{ - cardFlowInfo.put("open_status",null); + cardFlowInfo.put("upay_open_status",null); } saveClientAuditProcess(client.getIntValue("client_id"), open_status, cardFlowInfo.getIntValue("open_status"), "打回," + refuse_remark, manager,2); - clientCardFlowMapper.update(cardFlowInfo); + sysClientUpayProfileMapper.update(cardFlowInfo); try { if (client.getIntValue("source") == 4) { @@ -5713,11 +5715,11 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid String bd_user_name = client.getString("bd_user_name"); String client_moniker = "[" + client.getString("client_moniker") + "]"; String short_name = client.getString("short_name"); - JSONObject cardFlowInfo = clientCardFlowMapper.findClient(client.getInteger("client_id")); + JSONObject cardFlowInfo = sysClientUpayProfileMapper.findInfo(client.getInteger("client_id")); if(null == cardFlowInfo){ return; } - if (cardFlowInfo.getIntValue("open_status") == 1) { + if (cardFlowInfo.getIntValue("upay_open_status") == 1) { List complianceList = managerMapper.getOnlyCompliance(); if (complianceList != null && complianceList.size() > 0) { for (JSONObject compliance : complianceList) { @@ -5735,7 +5737,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } return; } - if (cardFlowInfo.getIntValue("open_status") == 3) { + if (cardFlowInfo.getIntValue("upay_open_status") == 3) { List bds = clientBDMapper.listClientBDInfoAvailable(client.getIntValue("client_id"), new Date()); for (JSONObject bd : bds) { String wxopenid = bd.getString("wx_openid"); @@ -5755,7 +5757,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } return; } - if (cardFlowInfo.getIntValue("open_status") == 4) { + if (cardFlowInfo.getIntValue("upay_open_status") == 4) { if (client.getIntValue("source") == 4 && !StringUtils.isNotEmpty(bd_user_name)) { bd_user_name = "自助开通商户"; } @@ -5778,7 +5780,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } return; } - if (cardFlowInfo.getIntValue("open_status") == 5) { + if (cardFlowInfo.getIntValue("upay_open_status") == 5) { List bds = clientBDMapper.listClientBDInfoAvailable(client.getIntValue("client_id"), new Date()); for (JSONObject bd : bds) { String wxopenid = bd.getString("wx_openid"); diff --git a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientMapper.xml index 086d71004..3e964120b 100644 --- a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientMapper.xml +++ b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientMapper.xml @@ -38,11 +38,17 @@ order by display_name SELECT cr.*,c.clean_days c_clean_days FROM sys_client_rates cr INNER JOIN sys_clients c on c.client_id= cr.client_id and c.is_valid = 1 - INNER JOIN sys_clients_card_flow cf ON cf.client_id = c.client_id AND ( cf.approve_result = 4 AND cf.open_status NOT IN (0,5) ) + INNER JOIN sys_clients_card_flow cf ON cf.client_id = c.client_id AND ( cf.approve_result 4 AND cf.open_status NOT IN (0,5) ) where cr.client_id = #{client_id} and cr.rate_name = #{rate_name} order by cr.expiry_time desc diff --git a/src/main/ui/static/commons/templates/promotiona_commit.html b/src/main/ui/static/commons/templates/promotiona_commit.html new file mode 100644 index 000000000..1ee5f2610 --- /dev/null +++ b/src/main/ui/static/commons/templates/promotiona_commit.html @@ -0,0 +1,19 @@ + + + \ No newline at end of file diff --git a/src/main/ui/static/payment/partner/partner-manage.js b/src/main/ui/static/payment/partner/partner-manage.js index 58f007f79..f29f5c844 100644 --- a/src/main/ui/static/payment/partner/partner-manage.js +++ b/src/main/ui/static/payment/partner/partner-manage.js @@ -424,6 +424,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter $scope.isComplianceOfCompanyName = false; $scope.isComplianceOfShortName = false; $scope.isComplianceOfBusinessStructure = false; + $scope.cardPromotionaparams={} var website = partner.data.company_website; if (website != null) { if (website.indexOf('http') != 0) { @@ -685,12 +686,15 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter //制作促销合同 $scope.exportCardPromotionaAgreegatePDF = function(){ - var title = 'Warning'; - $scope.cardPromotionaparams={} - var contentHtml = $sce.trustAsHtml('请选择优惠生效日:'+ '
    ' + - ' 请输入活动周期: '); + var title = '确认生成Promotional Offer合同'; + var promotiona_date=''; + var promotiona_period =''; + var contentHtml = $sce.trustAsHtml( + '请输入优惠生成日: '+ + ' (eg: 2020-02-01)' + + '
    ' + + '请输入活动周期数: ' + + ' (unit:week)'); var choises = [{label: '取消', className: 'btn-danger', key: '2', dismiss: true}, {label: '确认提交', className: 'btn-success', key: '1'}]; var content = ''; @@ -701,8 +705,12 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter choises: choises, contentHtml: contentHtml }).then(function (res) { - if(params != null){ - $http.get('/sys/partners/' + $scope.partner.client_moniker + '/export/aggregate/card_promotiona_agree_pdf').then(function () { + var date = document.getElementById("promotiona_date").value; + var period = document.getElementById("promotiona_period").value; + if(date=='' || period==''){ + commonDialog.alert({title: 'Error', content: '选项不得未空', type: 'error'}); + }else{ + $http.get('/sys/partners/' + $scope.partner.client_moniker + '/export/aggregate/card_promotiona_agree_pdf?date='+date+'&period='+period).then(function () { commonDialog.alert({ title: 'Success', content: 'Agreement File Generate Succeed! Please notify BD!', @@ -716,8 +724,8 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); }); } - }); + }); } $scope.Export = function () { From 22e8956d3415ac00270e2c07ae1aa43b1628a6f0 Mon Sep 17 00:00:00 2001 From: luoyang Date: Tue, 28 Apr 2020 15:42:28 +0800 Subject: [PATCH 16/40] fix --- .../payment/manage/mappers/system/ClientMapper.xml | 12 ++++++------ .../manage/mappers/system/ClientRateMapper.xml | 4 ++-- src/main/ui/static/payment/partner/partner-manage.js | 10 +++++----- .../static/payment/partner/templates/partners.html | 7 ++++--- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientMapper.xml index 3e964120b..dbdfc3ffb 100644 --- a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientMapper.xml +++ b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientMapper.xml @@ -141,20 +141,20 @@ OR (c.client_id NOT IN ( - SELECT client_id FROM sys_clients_card_flow + SELECT client_id FROM sys_client_upay_profile ) OR c.client_id IN ( - SELECT client_id FROM sys_clients_card_flow AS cardFlow - WHERE cardFlow.approve_result = 4 or approve_result = 1 + SELECT client_id FROM sys_client_upay_profile AS cardFlow + WHERE cardFlow.upay_approve_result = 4 or upay_approve_result = 1 )) AND (c.client_id NOT IN ( - SELECT client_id FROM sys_clients_card_flow + SELECT client_id FROM sys_client_upay_profile ) OR c.client_id IN ( - SELECT client_id FROM sys_clients_card_flow AS cardFlow - WHERE cardFlow.approve_result = 4 or approve_result = 1 + SELECT client_id FROM sys_client_upay_profile AS cardFlow + WHERE cardFlow.upay_approve_result = 4 or upay_approve_result = 1 )) diff --git a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientRateMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientRateMapper.xml index 3ab0d1fd2..469b5d65a 100644 --- a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientRateMapper.xml +++ b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientRateMapper.xml @@ -180,7 +180,7 @@ - \ No newline at end of file + diff --git a/src/main/ui/static/payment/partner/partner-manage.js b/src/main/ui/static/payment/partner/partner-manage.js index f29f5c844..daa561021 100644 --- a/src/main/ui/static/payment/partner/partner-manage.js +++ b/src/main/ui/static/payment/partner/partner-manage.js @@ -690,13 +690,13 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter var promotiona_date=''; var promotiona_period =''; var contentHtml = $sce.trustAsHtml( - '请输入优惠生成日: '+ - ' (eg: 2020-02-01)' + + '请输入优惠开始日期(eg:2020-02-01): '+ + '' + '
    ' + - '请输入活动周期数: ' + - ' (unit:week)'); + '请输入活动周数(unit:week): ' + + ''); var choises = [{label: '取消', className: 'btn-danger', key: '2', dismiss: true}, - {label: '确认提交', className: 'btn-success', key: '1'}]; + {label: '确认生成', className: 'btn-success', key: '1'}]; var content = ''; $scope.showCardPromotionaBg = true; commonDialog.confirm({ diff --git a/src/main/ui/static/payment/partner/templates/partners.html b/src/main/ui/static/payment/partner/templates/partners.html index 0b66ae73e..f2f38480f 100644 --- a/src/main/ui/static/payment/partner/templates/partners.html +++ b/src/main/ui/static/payment/partner/templates/partners.html @@ -487,7 +487,7 @@ -
    +
    通过({{partner.approve_time}}) 资料完善中 @@ -502,10 +502,11 @@ 绿色通道申请中 等待合规
    -
    + +
    资料完善中
    -
    +
    通过({{partner.upay_approve_time}}) 资料完善中 From b12b62f73efec281493e03503fe4bb847235f77a Mon Sep 17 00:00:00 2001 From: dulingling Date: Tue, 28 Apr 2020 16:28:31 +0800 Subject: [PATCH 17/40] =?UTF-8?q?Upd:=E4=BF=A1=E7=94=A8=E5=8D=A1=E5=90=88?= =?UTF-8?q?=E8=A7=84=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/impls/ClientManagerImpl.java | 32 +++---- src/main/ui/static/boot/manager-bootv2.js | 4 +- .../static/payment/partner/partner-manage.js | 2 +- .../partner/templates/partner_detail.html | 86 +++++++++---------- .../templates/partner_mw_auth_files.html | 3 + 5 files changed, 59 insertions(+), 68 deletions(-) diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index 60d784df4..7fedfb0f9 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -4762,24 +4762,13 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } JSONObject cardFlowInfo = sysClientUpayProfileMapper.findInfo(clientId); - if(null != cardFlowInfo){ - JSONObject cardFlow = new JSONObject(){{ - put("client_id",clientId); - put("upay_approve_result",4); - put("upay_open_status",1); - put("upay_approve_time",new Date()); - }}; - sysClientUpayProfileMapper.save(cardFlow); - }else{ - JSONObject cardFlow = new JSONObject(){{ - put("client_id",clientId); - put("upay_open_status",1); - put("upay_approve_result",4); - put("upay_approve_time",new Date()); - }}; - sysClientUpayProfileMapper.save(cardFlow); - } - + JSONObject cardFlow = new JSONObject(){{ + put("client_id",clientId); + put("upay_approve_result",4); + put("upay_open_status",1); + put("upay_approve_time",new Date()); + }}; + sysClientUpayProfileMapper.update(cardFlow); saveClientAuditProcess(client.getIntValue("client_id"), null, 1, "提交Compliance制作合同", manager,2); } @@ -7356,7 +7345,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } //获取数据源 int clientId = client.getInteger("client_id"); - JSONObject clientRate = clientRateMapper.latestCardChannelCleanDays("rpaypmt_card", clientId); + JSONObject clientRate = merchantInfoProvider.clientCurrentRate(clientId, new Date(), "rpaypmt_card"); if (clientRate == null) { throw new BadRequestException("rpaypmt_card rate Not configured"); } @@ -7372,7 +7361,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid info.put("partner_state", client.getString("state"));//洲 info.put("partner_bussiness_name", client.getString("business_name"));//商户商用名称 info.put("clean_days", client.getInteger("clean_days"));//T+规则清算天数 - info.put("partner_industry_mcc", upayProfileInfo.getString("mv_industy"));//信用卡注册商户行业编码 + info.put("partner_industry_mcc", upayProfileInfo.getString("mv_industry"));//信用卡注册商户行业编码 info.put("legal_bussiness", client.getString("contact_person") + " AS " + (client.containsKey("business_name")?client.getString("business_name"):client.getString("contact_person")) + " ABN " + client.getString("abn"));//拼接规则:法人名 AS 商用名称 ABD 编码 info.put("annual_rate",cardAnnualRate);//年费率 info.put("cost_per_transaction", clientRate.getString("transaction_fee"));//每次交易成本 @@ -7405,12 +7394,11 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid throw new BadRequestException("The merchant failed the audit!"); } int clientId = client.getInteger("client_id"); - JSONObject clientRate = clientRateMapper.latestCardChannelCleanDays("rpaypmt_card", clientId); + JSONObject clientRate = merchantInfoProvider.clientCurrentRate(clientId, new Date(), "rpaypmt_card"); if (clientRate == null) { throw new BadRequestException("rpaypmt_card rate Not configured"); } JSONObject cardRate = clientRate.getJSONObject("ext_rates"); - JSONObject bankAccountInfo = clientBankAccountMapper.clientBankAccounts(clientId).get(0); JSONObject info = new JSONObject(); info.put("down_date", convertDateEnglish(new Date()));//下载文件日期 diff --git a/src/main/ui/static/boot/manager-bootv2.js b/src/main/ui/static/boot/manager-bootv2.js index c592cbe37..fec641d86 100644 --- a/src/main/ui/static/boot/manager-bootv2.js +++ b/src/main/ui/static/boot/manager-bootv2.js @@ -76,8 +76,8 @@ require(['angular', 'jquery'], function (angular, $) { }); function boot(user) { - var paths = ['static/boot/managerMainAppv2', 'static/menu/managerMenu','static/analysis/org/analysis-org', 'static/analysis/report/analysis-report', 'static/analysis/monitoring/analysis-monitoring', 'static/analysis/bd/analysis-bd','static/analysis/trans-analysis']; - var moduleNames = ['managerMainAppv2', 'listMenuApp','analysisTransaction', 'analysisBD', 'analysisOrg', 'analysisMonitoring', 'analysisReport']; + var paths = ['static/boot/managerMainAppv2', 'static/menu/managerMenu','static/analysis/org/analysis-org', 'static/analysis/report/analysis-report', 'static/analysis/monitoring/analysis-monitoring', 'static/analysis/bd/analysis-bd','static/analysis/trans-analysis','static/payment/partner/add-partner']; + var moduleNames = ['managerMainAppv2', 'listMenuApp','analysisTransaction', 'analysisBD', 'analysisOrg', 'analysisMonitoring', 'analysisReport','addPartnerApp']; window.currentUser = user; angular.forEach(user.modules, function (mod) { paths.push(mod.js_path); diff --git a/src/main/ui/static/payment/partner/partner-manage.js b/src/main/ui/static/payment/partner/partner-manage.js index f29f5c844..524509d01 100644 --- a/src/main/ui/static/payment/partner/partner-manage.js +++ b/src/main/ui/static/payment/partner/partner-manage.js @@ -593,7 +593,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter choises: choises, contentHtml: contentHtml }).then(function () { - $http.put('/sys/partners/' + $scope.partner.client_moniker + '/card_promotiona_agree_pdf', {pass: 1}).then(function () { + $http.put('/sys/partners/' + $scope.partner.client_moniker + '/card_audit', {pass: 1}).then(function () { if ($scope.partner.approve_result == 2 && ($scope.partner.source == 1 || $scope.partner.source == 2)) { commonDialog.alert({ title: 'Success', diff --git a/src/main/ui/static/payment/partner/templates/partner_detail.html b/src/main/ui/static/payment/partner/templates/partner_detail.html index 7c83452cd..9e86ff7c5 100644 --- a/src/main/ui/static/payment/partner/templates/partner_detail.html +++ b/src/main/ui/static/payment/partner/templates/partner_detail.html @@ -238,27 +238,27 @@

    - Compliance (Refused :{{partner.refuse_remark}}) - (The Partner Using Green Channel Now!) 【目前状态】- - (自助申请)资料完善中 - (自助申请)已开通 - (自助申请)快速开通等待提交合规材料 - (自助申请)待审核(材料已提交) + (自助申请)资料完善中 + (自助申请)已开通 + (自助申请)快速开通等待提交合规材料 + (自助申请)待审核(材料已提交) - 资料完善中 - 待审核(合同制作中) - 合同制作完成 - BD处理中 - 待审核(合规文件已提交) - 通过 - 不通过 + 资料完善中 + 待审核(合同制作中) + 合同制作完成 + BD处理中 + 待审核(合规文件已提交) + 通过 + 不通过 (已禁用)

    @@ -267,20 +267,20 @@
    -
    +
    - -
    @@ -293,8 +293,8 @@ 下载Promotional Offer合同 - - + Notify BD @@ -310,11 +310,11 @@
    @@ -325,50 +325,50 @@
    + ng-class="{'box-warning':partner.upay_approve_result!=5,'box-danger':partner.upay_approve_result==5}">
    -

    Operation +

    Operation (Refused - :{{partner.card_flow_info.refuse_remark}} + :{{partner.upay_refuse_remark}} )(The Partner Using Green Channel Now!) 【目前状态】- - 资料完善中 - 待审核(合同制作中) - 合同制作完成 - BD处理中 - 待审核(合规文件已提交) - 通过 - 不通过 - 绿色通道申请中 + 资料完善中 + 待审核(合同制作中) + 合同制作完成 + BD处理中 + 待审核(合规文件已提交) + 通过 + 不通过 + 绿色通道申请中

    - 下载Letter Of Offer合同 - 下载Terms And Conditions合同 - 下载Promotional Offer合同 -
    +
    -
    +
    diff --git a/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html b/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html index 64e766aa7..33e4f82aa 100644 --- a/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html +++ b/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html @@ -254,3 +254,6 @@
    +
    + check +
    \ No newline at end of file From b53bba9e2e7ade696db4ce8f87938477f5152bbb Mon Sep 17 00:00:00 2001 From: luoyang Date: Tue, 28 Apr 2020 17:14:11 +0800 Subject: [PATCH 18/40] fix edit rate --- .../manage/merchants/core/impls/ClientManagerImpl.java | 5 +++++ src/main/ui/static/payment/partner/partner-manage.js | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index 7fedfb0f9..ee40d23c2 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -2148,6 +2148,11 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid configJson.put("manager_id", manager.getString("manager_id")); configJson.put("manager_name", manager.getString("username")); configJson.put("update_time", new Date()); + if (StringUtils.equalsIgnoreCase("rpaypmt_card", config.getRateName())) { + JSONObject extParams = configJson.getJSONObject("ext_rates"); + extParams.put("domestic_rate_value", config.getRateValue()); + configJson.put("ext_rates", extParams.toJSONString()); + } clientRateMapper.updateConfig(configJson); // if ("Rpay".equals(configJson.getString("rate_name"))) { // rpayApi.modifySurchargeConfig(client); diff --git a/src/main/ui/static/payment/partner/partner-manage.js b/src/main/ui/static/payment/partner/partner-manage.js index bd2932d21..2d8ee2ea5 100644 --- a/src/main/ui/static/payment/partner/partner-manage.js +++ b/src/main/ui/static/payment/partner/partner-manage.js @@ -3337,7 +3337,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter }, function (resp) { $scope.ctrl.sending = false; $scope.errmsg = resp.data.message; - }) + }); } else { $http.post('/sys/partners/' + clientMoniker + '/rates', $scope.rate).then(function () { $scope.ctrl.sending = false; @@ -3345,7 +3345,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter }, function (resp) { $scope.ctrl.sending = false; $scope.errmsg = resp.data.message; - }) + }); } } }]); From 6956fb0dc520edad2116450c86ea36d641624641 Mon Sep 17 00:00:00 2001 From: luoyang Date: Tue, 28 Apr 2020 17:17:39 +0800 Subject: [PATCH 19/40] =?UTF-8?q?fix=20=E9=A3=8E=E9=99=A9=E7=AD=89?= =?UTF-8?q?=E7=BA=A7=E5=8F=AA=E5=85=81=E8=AE=B8=E5=90=88=E8=A7=84=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../payment/partner/templates/partner_mw_auth_files.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html b/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html index 33e4f82aa..d5f0666a5 100644 --- a/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html +++ b/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html @@ -13,7 +13,7 @@

    Merchant Warrior商户风险评级 - +

    @@ -256,4 +256,4 @@
    \ No newline at end of file +
    From d3ccf5f984f458c20dfadc80e5c36840df8f7823 Mon Sep 17 00:00:00 2001 From: luoyang Date: Tue, 28 Apr 2020 17:54:49 +0800 Subject: [PATCH 20/40] =?UTF-8?q?add=20=E5=90=88=E8=A7=84=E6=9D=90?= =?UTF-8?q?=E6=96=99=E4=B8=8A=E4=BC=A0=E6=9D=83=E9=99=90=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/partner_cp_auth_files.html | 24 +++++++++---------- .../templates/partner_mw_auth_files.html | 22 ++++++++--------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/main/ui/static/payment/partner/templates/partner_cp_auth_files.html b/src/main/ui/static/payment/partner/templates/partner_cp_auth_files.html index 2c927ce0e..25b334899 100644 --- a/src/main/ui/static/payment/partner/templates/partner_cp_auth_files.html +++ b/src/main/ui/static/payment/partner/templates/partner_cp_auth_files.html @@ -112,7 +112,7 @@
    - @@ -130,7 +130,7 @@ - + @@ -152,7 +152,7 @@
    - @@ -167,7 +167,7 @@ - + @@ -194,7 +194,7 @@
    - @@ -210,7 +210,7 @@ - + @@ -238,7 +238,7 @@
    - @@ -254,7 +254,7 @@ - + @@ -275,7 +275,7 @@
    - @@ -291,7 +291,7 @@ - + @@ -311,7 +311,7 @@
    - @@ -330,7 +330,7 @@ - diff --git a/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html b/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html index d5f0666a5..f522ad69f 100644 --- a/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html +++ b/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html @@ -69,7 +69,7 @@
    - @@ -86,7 +86,7 @@
    - @@ -103,7 +103,7 @@
    - @@ -120,7 +120,7 @@
    - @@ -137,7 +137,7 @@
    - @@ -154,7 +154,7 @@
    - @@ -171,7 +171,7 @@
    - @@ -188,7 +188,7 @@
    - @@ -205,7 +205,7 @@
    - @@ -222,7 +222,7 @@
    - @@ -239,7 +239,7 @@
    - From 0984e606e29549cc81fd1db1cddb2f1dc690703e Mon Sep 17 00:00:00 2001 From: luoyang Date: Tue, 28 Apr 2020 17:55:30 +0800 Subject: [PATCH 21/40] fix common --- src/main/resources/application-common.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-common.yml b/src/main/resources/application-common.yml index f508af2eb..238e4f272 100644 --- a/src/main/resources/application-common.yml +++ b/src/main/resources/application-common.yml @@ -64,7 +64,7 @@ spring: time-between-eviction-runs-millis: 500 validation-query: select 1 mail: - host: smtp.o11ffice365.com + host: smtp.office365.com port: 587 thymeleaf: mode: HTML From 3b84cf18b6336a669ea4909b47a0e367f982b78e Mon Sep 17 00:00:00 2001 From: dulingling Date: Tue, 28 Apr 2020 17:58:16 +0800 Subject: [PATCH 22/40] =?UTF-8?q?Upd:=E4=BF=A1=E7=94=A8=E5=8D=A1=E5=90=88?= =?UTF-8?q?=E8=A7=84=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/impls/ClientManagerImpl.java | 22 ++++++++++-------- .../templates/pdf/letter_of_offer.pdf | Bin 187904 -> 186807 bytes 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index ee40d23c2..f0befed9a 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -5675,7 +5675,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid try { TemplateMessage msg = initTaskFinishTemplate(wxopenid, client_moniker + "已正式开通", "Compliance审核通过", ""); MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); - paymentApi.sendTemplateMessage(msg); +// paymentApi.sendTemplateMessage(msg); } catch (WechatException e) { logger.error("Wechat Message Error,open_status=5" + e.getMessage()); publisher.publishEvent(new WechatExceptionEvent(this, e, "Audit,open_status=5,openid=" + wxopenid)); @@ -5723,7 +5723,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); TemplateMessage msg = initSendCommissionTemplate(wxopenid, paymentApi.getTemplateId("commission"), "BD申请制作信用卡支付合同" + client_moniker, bd_user_name, "制作卡支付合同申请", "BD申请制作" + short_name + "的卡支付合同"); - paymentApi.sendTemplateMessage(msg); +// paymentApi.sendTemplateMessage(msg); } catch (WechatException e) { logger.error("Wechat Message Error,open_status=1" + e.getMessage()); publisher.publishEvent(new WechatExceptionEvent(this, e, "Audit,open_status=1,openid=" + wxopenid)); @@ -5741,7 +5741,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); TemplateMessage msg = initSendCommissionTemplate(wxopenid, paymentApi.getTemplateId("commission"), client_moniker + "信用卡支付合同制作完成", "Compliance", "合规材料", "上传完整合规材料,商户:" + short_name); - paymentApi.sendTemplateMessage(msg); +// paymentApi.sendTemplateMessage(msg); } catch (WechatException e) { logger.error("Wechat Message Error,open_status=3" + e.getMessage()); publisher.publishEvent(new WechatExceptionEvent(this, e, "Audit,open_status=3,openid=" + wxopenid)); @@ -5764,7 +5764,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); TemplateMessage msg = initSendCommissionTemplate(wxopenid, paymentApi.getTemplateId("commission"), client_moniker + "信用卡卡支付合规材料已提交", bd_user_name, "审核材料", "已提交合规材料,等待审核"); - paymentApi.sendTemplateMessage(msg); +// paymentApi.sendTemplateMessage(msg); } catch (WechatException e) { logger.error("Wechat Message Error,open_status=1" + e.getMessage()); publisher.publishEvent(new WechatExceptionEvent(this, e, "Audit,open_status=1,openid=" + wxopenid)); @@ -5783,7 +5783,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid try { TemplateMessage msg = initTaskFinishTemplate(wxopenid, client_moniker + "已正式开通", "Card Payment Compliance审核通过", ""); MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); - paymentApi.sendTemplateMessage(msg); +// paymentApi.sendTemplateMessage(msg); } catch (WechatException e) { logger.error("Wechat Message Error,open_status=5" + e.getMessage()); publisher.publishEvent(new WechatExceptionEvent(this, e, "Audit,open_status=5,openid=" + wxopenid)); @@ -7357,17 +7357,18 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid JSONObject cardRate = clientRate.getJSONObject("ext_rates"); JSONObject bankAccountInfo = clientBankAccountMapper.clientBankAccounts(clientId).get(0); JSONObject upayProfileInfo = sysClientUpayProfileMapper.findInfo(clientId); + JSONObject legalInfo = sysClientLegalPersonMapper.findRepresentativeInfo(clientId); //装在数据 JSONObject info = new JSONObject(); info.put("down_date", convertDateEnglish(new Date()));//下载文件日期 - info.put("bussiness_name", (client.containsKey("business_name")?client.getString("business_name"):client.getString("contact_person")) + " ABN");//商圈类型 + info.put("bussiness_name", (client.containsKey("business_name")?client.getString("business_name"):legalInfo.getString("representative_person")) + " "+client.getString("abn"));//商圈类型 info.put("partner_address", client.getString("address"));//商家店铺地址 info.put("partner_country", client.getString("country"));//国家 info.put("partner_state", client.getString("state"));//洲 info.put("partner_bussiness_name", client.getString("business_name"));//商户商用名称 info.put("clean_days", client.getInteger("clean_days"));//T+规则清算天数 - info.put("partner_industry_mcc", upayProfileInfo.getString("mv_industry"));//信用卡注册商户行业编码 - info.put("legal_bussiness", client.getString("contact_person") + " AS " + (client.containsKey("business_name")?client.getString("business_name"):client.getString("contact_person")) + " ABN " + client.getString("abn"));//拼接规则:法人名 AS 商用名称 ABD 编码 + info.put("partner_industry_mcc", upayProfileInfo.getString("mw_industry"));//信用卡注册商户行业编码 + info.put("legal_bussiness", legalInfo.getString("representative_person") + " AS " + (client.containsKey("business_name")?client.getString("business_name"):legalInfo.getString("representative_person")) + " ABN " + client.getString("abn"));//拼接规则:法人名 AS 商用名称 ABD 编码 info.put("annual_rate",cardAnnualRate);//年费率 info.put("cost_per_transaction", clientRate.getString("transaction_fee"));//每次交易成本 info.put("domestic_fee", cardRate.getString("domestic_rate_value"));//国内服务费 @@ -7404,15 +7405,16 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid throw new BadRequestException("rpaypmt_card rate Not configured"); } JSONObject cardRate = clientRate.getJSONObject("ext_rates"); + JSONObject legalInfo = sysClientLegalPersonMapper.findRepresentativeInfo(clientId); JSONObject info = new JSONObject(); info.put("down_date", convertDateEnglish(new Date()));//下载文件日期 - info.put("bussiness_name", (client.containsKey("business_name")?client.getString("business_name"):client.getString("contact_person")) + " ABN");//商圈类型 + info.put("bussiness_name", (client.containsKey("business_name")?client.getString("business_name"):legalInfo.getString("representative_person")) + " "+client.getString("abn"));//商圈类型 info.put("partner_address", client.getString("address"));//商家店铺地址 info.put("partner_country", client.getString("country"));//国家 info.put("partner_state", client.getString("state"));//洲 info.put("partner_bussiness_name", client.getString("business_name"));//商户商用名称 - info.put("legal_bussiness", client.getString("contact_person") + " AS " + (client.containsKey("business_name")?client.getString("business_name"):client.getString("contact_person")) + " ABN " + client.getString("abn"));//拼接规则:法人名 AS 商用名称 ABD 编码 + info.put("legal_bussiness", legalInfo.getString("representative_person") + " AS " + (client.containsKey("business_name")?client.getString("business_name"):legalInfo.getString("representative_person")) + " ABN " + client.getString("abn"));//拼接规则:法人名 AS 商用名称 ABD 编码 info.put("domestic_fee", cardRate.getString("domestic_rate_value"));//国内服务费 info.put("international_fee", cardRate.getString("overseas_rate_value"));//国际服务费 info.put("promotional_effective_date", promotionalEffectiveDate); diff --git a/src/main/resources/templates/pdf/letter_of_offer.pdf b/src/main/resources/templates/pdf/letter_of_offer.pdf index ec8454d9176adb2e2b7bfc77d94c21c1594e6c07..2aa701a83747f56cb97fad26dcfc00e6285dfcc9 100644 GIT binary patch delta 51073 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 delta 52277 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�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 WbhL(oWJDZr4>hy?ex#)%fW}|ZuEOL1 From 5e8ac09f23a43aff814081b4aa74a8b61f54736b Mon Sep 17 00:00:00 2001 From: dulingling Date: Tue, 28 Apr 2020 17:59:42 +0800 Subject: [PATCH 23/40] =?UTF-8?q?Upd:=E4=BF=A1=E7=94=A8=E5=8D=A1=E5=90=88?= =?UTF-8?q?=E8=A7=84=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/static/payment/partner/templates/partner_detail.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/ui/static/payment/partner/templates/partner_detail.html b/src/main/ui/static/payment/partner/templates/partner_detail.html index 9e86ff7c5..9cb68dda6 100644 --- a/src/main/ui/static/payment/partner/templates/partner_detail.html +++ b/src/main/ui/static/payment/partner/templates/partner_detail.html @@ -268,10 +268,8 @@
    - - - 制作卡支付合同 + 制作信用卡支付合同 制作促销合同
    From 85ae04c0cd06b2eb229b539de37c9a5b15ef2e5b Mon Sep 17 00:00:00 2001 From: dulingling Date: Tue, 28 Apr 2020 18:00:43 +0800 Subject: [PATCH 24/40] =?UTF-8?q?Upd:=E4=BF=A1=E7=94=A8=E5=8D=A1=E5=90=88?= =?UTF-8?q?=E8=A7=84=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/static/payment/partner/templates/partner_detail.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/ui/static/payment/partner/templates/partner_detail.html b/src/main/ui/static/payment/partner/templates/partner_detail.html index 9cb68dda6..4cd4b5a2c 100644 --- a/src/main/ui/static/payment/partner/templates/partner_detail.html +++ b/src/main/ui/static/payment/partner/templates/partner_detail.html @@ -1303,7 +1303,7 @@
    From eabb8cba1200d8100e614ee2828a7ca2cbe798f5 Mon Sep 17 00:00:00 2001 From: dulingling Date: Tue, 28 Apr 2020 18:02:59 +0800 Subject: [PATCH 25/40] =?UTF-8?q?Upd:=E4=BF=A1=E7=94=A8=E5=8D=A1=E5=90=88?= =?UTF-8?q?=E8=A7=84=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../merchants/core/impls/ClientManagerImpl.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index f0befed9a..3b6809dad 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -4745,7 +4745,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid clientModifySupport.processClientModify(openStatusModify); saveClientAuditProcess(client.getIntValue("client_id"), null, 1, "提交Card Payment Compliance制作合同", manager,1); if (manager != null) { - // sendAgreeFileMsgtoCompliance(client, manager.getString("display_name")); + sendAgreeFileMsgtoCompliance(client, manager.getString("display_name")); sendCommissionWechatMessage(client); } } @@ -5675,7 +5675,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid try { TemplateMessage msg = initTaskFinishTemplate(wxopenid, client_moniker + "已正式开通", "Compliance审核通过", ""); MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); -// paymentApi.sendTemplateMessage(msg); + paymentApi.sendTemplateMessage(msg); } catch (WechatException e) { logger.error("Wechat Message Error,open_status=5" + e.getMessage()); publisher.publishEvent(new WechatExceptionEvent(this, e, "Audit,open_status=5,openid=" + wxopenid)); @@ -5723,7 +5723,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); TemplateMessage msg = initSendCommissionTemplate(wxopenid, paymentApi.getTemplateId("commission"), "BD申请制作信用卡支付合同" + client_moniker, bd_user_name, "制作卡支付合同申请", "BD申请制作" + short_name + "的卡支付合同"); -// paymentApi.sendTemplateMessage(msg); + paymentApi.sendTemplateMessage(msg); } catch (WechatException e) { logger.error("Wechat Message Error,open_status=1" + e.getMessage()); publisher.publishEvent(new WechatExceptionEvent(this, e, "Audit,open_status=1,openid=" + wxopenid)); @@ -5741,7 +5741,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); TemplateMessage msg = initSendCommissionTemplate(wxopenid, paymentApi.getTemplateId("commission"), client_moniker + "信用卡支付合同制作完成", "Compliance", "合规材料", "上传完整合规材料,商户:" + short_name); -// paymentApi.sendTemplateMessage(msg); + paymentApi.sendTemplateMessage(msg); } catch (WechatException e) { logger.error("Wechat Message Error,open_status=3" + e.getMessage()); publisher.publishEvent(new WechatExceptionEvent(this, e, "Audit,open_status=3,openid=" + wxopenid)); @@ -5764,7 +5764,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); TemplateMessage msg = initSendCommissionTemplate(wxopenid, paymentApi.getTemplateId("commission"), client_moniker + "信用卡卡支付合规材料已提交", bd_user_name, "审核材料", "已提交合规材料,等待审核"); -// paymentApi.sendTemplateMessage(msg); + paymentApi.sendTemplateMessage(msg); } catch (WechatException e) { logger.error("Wechat Message Error,open_status=1" + e.getMessage()); publisher.publishEvent(new WechatExceptionEvent(this, e, "Audit,open_status=1,openid=" + wxopenid)); @@ -5783,7 +5783,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid try { TemplateMessage msg = initTaskFinishTemplate(wxopenid, client_moniker + "已正式开通", "Card Payment Compliance审核通过", ""); MpWechatApi paymentApi = mpWechatApiProvider.getNewPaymentApi(); -// paymentApi.sendTemplateMessage(msg); + paymentApi.sendTemplateMessage(msg); } catch (WechatException e) { logger.error("Wechat Message Error,open_status=5" + e.getMessage()); publisher.publishEvent(new WechatExceptionEvent(this, e, "Audit,open_status=5,openid=" + wxopenid)); From 4643a9ffa8e689404cb2fdbacde990a144aef5cb Mon Sep 17 00:00:00 2001 From: dulingling Date: Tue, 28 Apr 2020 18:04:37 +0800 Subject: [PATCH 26/40] =?UTF-8?q?Upd:=E4=BF=A1=E7=94=A8=E5=8D=A1=E5=90=88?= =?UTF-8?q?=E8=A7=84=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../payment/manage/merchants/core/impls/ClientManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index 3b6809dad..6b667a1ad 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -4745,7 +4745,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid clientModifySupport.processClientModify(openStatusModify); saveClientAuditProcess(client.getIntValue("client_id"), null, 1, "提交Card Payment Compliance制作合同", manager,1); if (manager != null) { - sendAgreeFileMsgtoCompliance(client, manager.getString("display_name")); +// sendAgreeFileMsgtoCompliance(client, manager.getString("display_name")); sendCommissionWechatMessage(client); } } From c0710d4f3826af6dca950713c7e7df05c278d6ea Mon Sep 17 00:00:00 2001 From: dulingling Date: Tue, 28 Apr 2020 18:08:10 +0800 Subject: [PATCH 27/40] =?UTF-8?q?Upd:=E4=BF=A1=E7=94=A8=E5=8D=A1=E5=90=88?= =?UTF-8?q?=E8=A7=84=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/ui/static/payment/partner/partner-manage.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/ui/static/payment/partner/partner-manage.js b/src/main/ui/static/payment/partner/partner-manage.js index 2d8ee2ea5..c363162d4 100644 --- a/src/main/ui/static/payment/partner/partner-manage.js +++ b/src/main/ui/static/payment/partner/partner-manage.js @@ -668,17 +668,17 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter //制作卡支付合同 $scope.exportCardAgreegatePDF = function(){ - $scope.showCardBg = true; + $scope.showBg = true; $http.get('/sys/partners/' + $scope.partner.client_moniker + '/export/aggregate/card_agree_pdf').then(function () { commonDialog.alert({ title: 'Success', content: 'Agreement File Generate Succeed! Please notify BD!', type: 'success' }); - $scope.showCardBg = false; + $scope.showBg = false; $state.reload(); }, function (resp) { - $scope.showCardBg = false; + $scope.showBg = false; $state.reload(); commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); }); @@ -698,7 +698,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter var choises = [{label: '取消', className: 'btn-danger', key: '2', dismiss: true}, {label: '确认生成', className: 'btn-success', key: '1'}]; var content = ''; - $scope.showCardPromotionaBg = true; + $scope.showBg = true; commonDialog.confirm({ title: title, content: content, @@ -716,10 +716,10 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter content: 'Agreement File Generate Succeed! Please notify BD!', type: 'success' }); - $scope.showCardPromotionaBg = false; + $scope.showBg = false; $state.reload(); }, function (resp) { - $scope.showCardPromotionaBg = false; + $scope.showBg = false; $state.reload(); commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); }); From b94cad3e5f5adcf47590bb4aba81c39f924c714f Mon Sep 17 00:00:00 2001 From: dulingling Date: Tue, 28 Apr 2020 19:16:49 +0800 Subject: [PATCH 28/40] =?UTF-8?q?Upd:=E4=BF=A1=E7=94=A8=E5=8D=A1=E5=90=88?= =?UTF-8?q?=E8=A7=84=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/static/payment/partner/partner-manage.js | 3 ++- .../partner/templates/partner_bankaccounts.html | 2 +- .../payment/partner/templates/partner_detail.html | 13 +++++-------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/ui/static/payment/partner/partner-manage.js b/src/main/ui/static/payment/partner/partner-manage.js index c363162d4..199dc4bb3 100644 --- a/src/main/ui/static/payment/partner/partner-manage.js +++ b/src/main/ui/static/payment/partner/partner-manage.js @@ -698,13 +698,14 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter var choises = [{label: '取消', className: 'btn-danger', key: '2', dismiss: true}, {label: '确认生成', className: 'btn-success', key: '1'}]; var content = ''; - $scope.showBg = true; + commonDialog.confirm({ title: title, content: content, choises: choises, contentHtml: contentHtml }).then(function (res) { + $scope.showBg = true; var date = document.getElementById("promotiona_date").value; var period = document.getElementById("promotiona_period").value; if(date=='' || period==''){ diff --git a/src/main/ui/static/payment/partner/templates/partner_bankaccounts.html b/src/main/ui/static/payment/partner/templates/partner_bankaccounts.html index 81a134cc8..9ff619fa9 100644 --- a/src/main/ui/static/payment/partner/templates/partner_bankaccounts.html +++ b/src/main/ui/static/payment/partner/templates/partner_bankaccounts.html @@ -214,7 +214,7 @@
  • CB_BankPay
  • Card Payment
  • Direct Debit
  • - diff --git a/src/main/ui/static/payment/partner/templates/partner_detail.html b/src/main/ui/static/payment/partner/templates/partner_detail.html index 4cd4b5a2c..5a7e44e87 100644 --- a/src/main/ui/static/payment/partner/templates/partner_detail.html +++ b/src/main/ui/static/payment/partner/templates/partner_detail.html @@ -60,10 +60,9 @@
    -
    -

    Compliance Cross-border payment Compliance (Refused :{{partner.refuse_remark}}) @@ -238,12 +237,10 @@

    - Compliance (Refused - :{{partner.refuse_remark}}) - (The Partner Using Green Channel Now!) + Card Payment Compliance + (Refused + :{{partner.upay_refuse_remark}}) + 【目前状态】- (自助申请)资料完善中 From f6cbf6b35d038620365c99f7cdfd0a3135b92df7 Mon Sep 17 00:00:00 2001 From: dulingling Date: Tue, 28 Apr 2020 19:20:48 +0800 Subject: [PATCH 29/40] =?UTF-8?q?Upd:=E4=BF=A1=E7=94=A8=E5=8D=A1=E5=90=88?= =?UTF-8?q?=E8=A7=84=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/ui/static/boot/manager-bootv2.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/ui/static/boot/manager-bootv2.js b/src/main/ui/static/boot/manager-bootv2.js index fec641d86..c592cbe37 100644 --- a/src/main/ui/static/boot/manager-bootv2.js +++ b/src/main/ui/static/boot/manager-bootv2.js @@ -76,8 +76,8 @@ require(['angular', 'jquery'], function (angular, $) { }); function boot(user) { - var paths = ['static/boot/managerMainAppv2', 'static/menu/managerMenu','static/analysis/org/analysis-org', 'static/analysis/report/analysis-report', 'static/analysis/monitoring/analysis-monitoring', 'static/analysis/bd/analysis-bd','static/analysis/trans-analysis','static/payment/partner/add-partner']; - var moduleNames = ['managerMainAppv2', 'listMenuApp','analysisTransaction', 'analysisBD', 'analysisOrg', 'analysisMonitoring', 'analysisReport','addPartnerApp']; + var paths = ['static/boot/managerMainAppv2', 'static/menu/managerMenu','static/analysis/org/analysis-org', 'static/analysis/report/analysis-report', 'static/analysis/monitoring/analysis-monitoring', 'static/analysis/bd/analysis-bd','static/analysis/trans-analysis']; + var moduleNames = ['managerMainAppv2', 'listMenuApp','analysisTransaction', 'analysisBD', 'analysisOrg', 'analysisMonitoring', 'analysisReport']; window.currentUser = user; angular.forEach(user.modules, function (mod) { paths.push(mod.js_path); From 3e151f1ef8916fef7fd91eb740c7e5a3f8c4c11a Mon Sep 17 00:00:00 2001 From: luoyang Date: Tue, 28 Apr 2020 19:53:41 +0800 Subject: [PATCH 30/40] fix --- .../merchants/beans/ClientRegisterInfo.java | 28 +++++----- .../core/impls/ClientManagerImpl.java | 8 ++- .../ui/static/payment/partner/add-partner.js | 11 +++- .../partner/templates/add_partner.html | 53 +++++++++---------- .../partner/templates/partner_edit.html | 47 ++++++++-------- .../templates/partner_payment_info.html | 24 --------- 6 files changed, 79 insertions(+), 92 deletions(-) diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientRegisterInfo.java b/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientRegisterInfo.java index e6d7d0dbe..e7764f981 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientRegisterInfo.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientRegisterInfo.java @@ -3,7 +3,6 @@ package au.com.royalpay.payment.manage.merchants.beans; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.annotation.JSONField; -import org.apache.commons.lang3.StringUtils; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; @@ -115,8 +114,6 @@ public class ClientRegisterInfo { private String client_pay_desc; @JSONField(name = "it_contact_person_email") private String itContactPersonEmail; - @JSONField(name = "client_type") - private String clientType; @JSONField(name = "acceptor_name") private String acceptorName; @JSONField(name = "expected_card_revenue") @@ -127,7 +124,10 @@ public class ClientRegisterInfo { private String mwIndustry; @JSONField(name = "enable_international_card") private boolean enableInternaltionCard; - + @JSONField(name = "enable_cross_payment") + private boolean enableCrossPayment; + @JSONField(name = "enable_card_payment") + private boolean enableCardPayment; public JSONObject insertObject() { if (industry == null) { @@ -140,10 +140,6 @@ public class ClientRegisterInfo { return res; } - public boolean enableCardPayment() { - return StringUtils.equalsIgnoreCase("card-payment", clientType) || StringUtils.equalsIgnoreCase("all", clientType); - } - public JSONObject updateObject() { JSONObject obj = insertObject(); obj.remove("client_moniker"); @@ -622,11 +618,19 @@ public class ClientRegisterInfo { this.mwIndustry = mwIndustry; } - public String getClientType() { - return clientType; + public boolean isEnableCardPayment() { + return enableCardPayment; + } + + public boolean isEnableCrossPayment() { + return enableCrossPayment; + } + + public void setEnableCardPayment(boolean enableCardPayment) { + this.enableCardPayment = enableCardPayment; } - public void setClientType(String clientType) { - this.clientType = clientType; + public void setEnableCrossPayment(boolean enableCrossPayment) { + this.enableCrossPayment = enableCrossPayment; } } diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index 6b667a1ad..05ec8fbfa 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -834,11 +834,13 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid clientConfig.put("client_moniker", partner.getString("client_moniker")); clientConfig.put("client_pay_type", partner.getString("client_pay_type")); clientConfig.put("client_pay_desc", partner.get("client_pay_desc")); + clientConfig.put("enable_cross_payment", partner.get("enable_cross_payment")); + clientConfig.put("enable_card_payment", partner.get("enable_card_payment")); clientConfigService.save(clientConfig); permissionPartnerManagerImpl.permissionClientModuleSave(partner.getIntValue("client_id"), partner.getString("client_moniker")); saveLegalAndMarketingInfo(partner); - if (registery.enableCardPayment()) { + if (registery.isEnableCardPayment()) { sysClientUpayProfileMapper.save(partner); } } catch (Exception e) { @@ -917,7 +919,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid sysClientLegalPersonMapper.save(representativeInfo); } - if (info.enableCardPayment()) { + if (info.isEnableCardPayment()) { JSONObject upay = sysClientUpayProfileMapper.findInfo(clientId); if (upay == null) { sysClientUpayProfileMapper.save(updateInfo); @@ -942,6 +944,8 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid JSONObject clientConfig = new JSONObject(); clientConfig.put("client_id", clientId); clientConfig.put("client_moniker", client.getString("client_moniker")); + clientConfig.put("enable_cross_payment", updateInfo.getBooleanValue("enable_cross_payment")); + clientConfig.put("enable_card_payment", updateInfo.getBooleanValue("enable_card_payment")); if (StringUtils.isNotBlank(updateInfo.getString("client_pay_type")) && StringUtils.isNotBlank(updateInfo.getString("client_pay_desc"))) { clientConfig.put("client_pay_type", updateInfo.getString("client_pay_type")); clientConfig.put("client_pay_desc", updateInfo.getString("client_pay_desc")); diff --git a/src/main/ui/static/payment/partner/add-partner.js b/src/main/ui/static/payment/partner/add-partner.js index 8f2e8ae34..821e49bd0 100644 --- a/src/main/ui/static/payment/partner/add-partner.js +++ b/src/main/ui/static/payment/partner/add-partner.js @@ -38,7 +38,8 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter } else { $scope.partner = {timezone: 'Australia/Melbourne'}; } - $scope.partner.client_type = 'cross-border'; + $scope.partner.enable_cross_payment = true; + $scope.partner.enable_cross_payment = false; $scope.initMerchantCode = function () { $http.get('/sys/partners/init/merchant_code').then(function (response) { $scope.partner.client_moniker = response.data.partner_code; @@ -61,6 +62,10 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter } }; $scope.partner.sameAsContactPerson = false; + + $scope.enablePaymentType = function (type) { + $scope.partner[type] = !$scope.partner[type]; + }; $scope.checkboxOnclick = function (){ $scope.partner.sameAsContactPerson = !($scope.partner.sameAsContactPerson); if($scope.partner.sameAsContactPerson) { @@ -490,6 +495,10 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter $scope.partner.marketing_wechatid = $scope.partner.representativeInfo.marketing_wechatid; } + $scope.enablePaymentType = function (type) { + $scope.partner[type] = !$scope.partner[type]; + }; + function hasRole() { var rolenum; switch (sessionStorage.getItem('role')) { diff --git a/src/main/ui/static/payment/partner/templates/add_partner.html b/src/main/ui/static/payment/partner/templates/add_partner.html index 8cdacf735..45deacc9b 100644 --- a/src/main/ui/static/payment/partner/templates/add_partner.html +++ b/src/main/ui/static/payment/partner/templates/add_partner.html @@ -40,14 +40,11 @@

    -
    @@ -166,7 +163,7 @@

    -
    @@ -188,7 +185,7 @@
    -
    @@ -218,8 +215,8 @@
    - + ng-if="partner.business_structure != 'Company' || partner.enable_card_payment"> +
    + ng-if="partner.business_structure == 'Company' && partner.enable_cross_payment">
    线上 -
    -
    +
    @@ -421,7 +418,7 @@
    -
    +
    @@ -492,7 +489,7 @@
    -
    +
    1:  @@ -524,7 +521,7 @@
    -
    @@ -540,7 +537,7 @@
    -
    @@ -560,7 +557,7 @@
    -
    +
    Alipay Information  (Optional)
    @@ -744,7 +741,7 @@
    -
    +
    @@ -869,9 +866,9 @@
    -
    -
      Marketing Person
    -
    +
    +
      Marketing Person
    +
    @@ -1251,7 +1248,7 @@
    -
    @@ -1270,7 +1267,7 @@
    -
    @@ -1290,7 +1287,7 @@
    -
    @@ -1308,7 +1305,7 @@
    -
    +
    diff --git a/src/main/ui/static/payment/partner/templates/partner_edit.html b/src/main/ui/static/payment/partner/templates/partner_edit.html index b525a376f..b2bd550f7 100644 --- a/src/main/ui/static/payment/partner/templates/partner_edit.html +++ b/src/main/ui/static/payment/partner/templates/partner_edit.html @@ -36,14 +36,11 @@
    -
    @@ -182,7 +179,7 @@
    -
    @@ -201,7 +198,7 @@
    -
    @@ -218,7 +215,7 @@
    -
    @@ -341,7 +338,7 @@ ng-click="toggleClientPayType('1')"> 线上 -
    -
    +
    @@ -408,7 +405,7 @@
    -
    +
    @@ -479,7 +476,7 @@
    -
    +
    1:  @@ -510,7 +507,7 @@
    -
    @@ -526,7 +523,7 @@
    -
    @@ -546,7 +543,7 @@
    -
    +
    Alipay Information   (Optional)
    @@ -671,7 +668,7 @@
    -
    +
    @@ -783,8 +780,8 @@
    -
      Marketing Person
    -
    +
      Marketing Person
    +
    @@ -1157,7 +1154,7 @@
    -
    @@ -1176,7 +1173,7 @@
    -
    @@ -1195,7 +1192,7 @@
    -
    @@ -1213,7 +1210,7 @@
    -
    +
    diff --git a/src/main/ui/static/payment/partner/templates/partner_payment_info.html b/src/main/ui/static/payment/partner/templates/partner_payment_info.html index 6d9aff34c..05445da42 100644 --- a/src/main/ui/static/payment/partner/templates/partner_payment_info.html +++ b/src/main/ui/static/payment/partner/templates/partner_payment_info.html @@ -205,36 +205,12 @@
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    From 1643d25ed2295ca740385757fc9cb7ca6250832e Mon Sep 17 00:00:00 2001 From: dulingling Date: Tue, 28 Apr 2020 19:59:04 +0800 Subject: [PATCH 31/40] =?UTF-8?q?Upd:=E4=BF=A1=E7=94=A8=E5=8D=A1=E5=90=88?= =?UTF-8?q?=E8=A7=84=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/impls/ClientManagerImpl.java | 4 ++- .../manage/mappers/system/ClientMapper.xml | 7 ++-- .../partner/templates/partner_detail.html | 13 +++----- .../payment/partner/templates/partners.html | 32 ++++++++++--------- 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index 6b667a1ad..2c0dda9b0 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -466,7 +466,9 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid client.put("show_all_permission", checkBDPermission > 0); if (checkBDPermission > 0) { JSONObject org = orgMapper.findOne(manager.getIntValue("org_id")); - boolean bdRateEditable = client.getIntValue("approve_result") != 1 || org.getBooleanValue("rate_editable"); + boolean bdRateEditable = client.getIntValue("approve_result") != 1 || + (client.getIntValue("upay_approve_result") !=1 && !client.containsKey("upay_approve_result") && client.getIntValue("upay_approve_result") !=4) + || org.getBooleanValue("rate_editable"); client.put("rate_editable", bdRateEditable); } else { client.put("company_phone", "******"); diff --git a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientMapper.xml index dbdfc3ffb..c3d60cc83 100644 --- a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientMapper.xml +++ b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientMapper.xml @@ -44,10 +44,13 @@ scup.upay_approve_time, scup.upay_refuse_remark, scup.upay_approve_email_send, - scup.upay_approve_email_id + scup.upay_approve_email_id, + config.enable_cross_payment, + config.enable_card_payment FROM sys_clients c inner join sys_client_config cc on cc.client_id = c.client_id inner join sys_org o on o.org_id=c.org_id + inner join sys_client_config config on c.client_id = config.client_id left join sys_client_upay_profile scup on scup.client_id = c.client_id INNER JOIN sys_client_bd d ON c.client_id = d.client_id AND d.bd_id = #{bd_user} and @@ -417,7 +420,7 @@ from sys_clients 跨境支付|Cross-border Payment
  • - 卡支付|Card Payment + 卡支付|Card Payment
  • diff --git a/src/main/ui/static/payment/partner/templates/partner_bankaccounts.html b/src/main/ui/static/payment/partner/templates/partner_bankaccounts.html index 9ff619fa9..36ef11d4d 100644 --- a/src/main/ui/static/payment/partner/templates/partner_bankaccounts.html +++ b/src/main/ui/static/payment/partner/templates/partner_bankaccounts.html @@ -214,9 +214,9 @@
  • CB_BankPay
  • Card Payment
  • Direct Debit
  • - +
    diff --git a/src/main/ui/static/payment/partner/templates/partner_detail.html b/src/main/ui/static/payment/partner/templates/partner_detail.html index ce2e83288..811b02888 100644 --- a/src/main/ui/static/payment/partner/templates/partner_detail.html +++ b/src/main/ui/static/payment/partner/templates/partner_detail.html @@ -363,7 +363,7 @@
    diff --git a/src/main/ui/static/payment/partner/templates/partner_edit.html b/src/main/ui/static/payment/partner/templates/partner_edit.html index b2bd550f7..01afef275 100644 --- a/src/main/ui/static/payment/partner/templates/partner_edit.html +++ b/src/main/ui/static/payment/partner/templates/partner_edit.html @@ -17,6 +17,10 @@ .form-control-span{ height: 34px; } + .check-box { + zoom: 130%; + margin-right: 5px; + }

    @@ -37,10 +41,16 @@ From f019290e2c43c9587156a752846c1c378a9cc0dd Mon Sep 17 00:00:00 2001 From: luoyang Date: Wed, 29 Apr 2020 12:03:29 +0800 Subject: [PATCH 35/40] =?UTF-8?q?fix=20=E5=90=88=E5=90=8C=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0=E6=8C=89=E9=92=AE=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/partner_cp_auth_files.html | 24 +++++++++---------- .../templates/partner_mw_auth_files.html | 24 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/main/ui/static/payment/partner/templates/partner_cp_auth_files.html b/src/main/ui/static/payment/partner/templates/partner_cp_auth_files.html index 25b334899..c1b35090d 100644 --- a/src/main/ui/static/payment/partner/templates/partner_cp_auth_files.html +++ b/src/main/ui/static/payment/partner/templates/partner_cp_auth_files.html @@ -112,7 +112,7 @@
    - @@ -130,7 +130,7 @@
    @@ -152,7 +152,7 @@
    - @@ -167,7 +167,7 @@
    @@ -194,7 +194,7 @@
    - @@ -210,7 +210,7 @@
    @@ -238,7 +238,7 @@
    - @@ -254,7 +254,7 @@
    @@ -275,7 +275,7 @@
    - @@ -291,7 +291,7 @@
    @@ -311,7 +311,7 @@
    - @@ -330,7 +330,7 @@ - diff --git a/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html b/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html index dd8df6229..37833aa4b 100644 --- a/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html +++ b/src/main/ui/static/payment/partner/templates/partner_mw_auth_files.html @@ -69,7 +69,7 @@
    - @@ -86,7 +86,7 @@
    - @@ -103,7 +103,7 @@
    - @@ -120,7 +120,7 @@
    - @@ -137,7 +137,7 @@
    - @@ -154,7 +154,7 @@
    - @@ -171,7 +171,7 @@
    - @@ -188,7 +188,7 @@
    - @@ -205,7 +205,7 @@
    - @@ -222,7 +222,7 @@
    - @@ -239,7 +239,7 @@
    - @@ -256,7 +256,7 @@
    - From 0eb6734c1dc5d8768ca6d2c3b260019a7ea02564 Mon Sep 17 00:00:00 2001 From: luoyang Date: Wed, 29 Apr 2020 13:21:50 +0800 Subject: [PATCH 36/40] =?UTF-8?q?fix=20=E6=8A=BC=E9=87=91=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../payment/manage/merchants/core/impls/ClientManagerImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index 92da4fffa..db524b05b 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -7380,7 +7380,8 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid info.put("cost_per_transaction", clientRate.getString("transaction_fee"));//每次交易成本 info.put("domestic_fee", cardRate.getString("domestic_rate_value"));//国内服务费 info.put("international_fee", cardRate.getString("overseas_rate_value"));//国际服务费 - info.put("account_reserve", cardAccountReserve);//账户储备金 + BigDecimal reserve = (upayProfileInfo.getBigDecimal("expected_card_revenue").multiply(new BigDecimal(0.005)).setScale(0, RoundingMode.HALF_UP)); + info.put("account_reserve", reserve.compareTo(new BigDecimal(200)) <= 0 ? new BigDecimal(200).toPlainString() : reserve.toPlainString());//账户储备金 //银行账号信息 info.put("account_name", bankAccountInfo.getString("account_name"));// info.put("bsb", bankAccountInfo.getString("bsb_no")); From c300ef933b1e6fd52f637997f883ad75869b4bcd Mon Sep 17 00:00:00 2001 From: luoyang Date: Wed, 29 Apr 2020 13:23:31 +0800 Subject: [PATCH 37/40] fix yml --- src/main/resources/application-common.yml | 3 +++ src/main/resources/application.yml | 5 ----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/resources/application-common.yml b/src/main/resources/application-common.yml index 238e4f272..6932e382e 100644 --- a/src/main/resources/application-common.yml +++ b/src/main/resources/application-common.yml @@ -73,3 +73,6 @@ spring: preferred-json-mapper: fastjson stockholder: mails: leo.huang@royalpay.com.au +client_card: + account_reserve: 1000 + annual_rate: 0 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 4890b713f..2edc05835 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -68,11 +68,6 @@ app: tax: type: GST -client_card: - account_reserve: 1000 - annual_rate: 0 - - apple: message: apns: From 17c166eb6e7349e16fe174f8ac8ef1d5aa0b94bd Mon Sep 17 00:00:00 2001 From: luoyang Date: Wed, 29 Apr 2020 13:29:43 +0800 Subject: [PATCH 38/40] fix partner --- src/main/ui/static/payment/partner/add-partner.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/ui/static/payment/partner/add-partner.js b/src/main/ui/static/payment/partner/add-partner.js index ad947fe1d..ac6ad6580 100644 --- a/src/main/ui/static/payment/partner/add-partner.js +++ b/src/main/ui/static/payment/partner/add-partner.js @@ -265,6 +265,10 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter }); return; } + if (!$scope.partner.enable_cross_payment && !$scope.partner.enable_card_payment) { + alert("商户至少开通一种支付方式,请检查是否选择了跨境支付或卡支付!"); + return; + } if ($scope.partner.company_name.indexOf("Migration") != -1) { alert("Company Name包含敏感词汇,请检查后重新提交!"); From 12420c022154eef0afeec3103f608db5bc03c14e Mon Sep 17 00:00:00 2001 From: luoyang Date: Wed, 29 Apr 2020 13:33:01 +0800 Subject: [PATCH 39/40] fix partner --- src/main/ui/static/boot/manager-bootv2.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/ui/static/boot/manager-bootv2.js b/src/main/ui/static/boot/manager-bootv2.js index fec641d86..c592cbe37 100644 --- a/src/main/ui/static/boot/manager-bootv2.js +++ b/src/main/ui/static/boot/manager-bootv2.js @@ -76,8 +76,8 @@ require(['angular', 'jquery'], function (angular, $) { }); function boot(user) { - var paths = ['static/boot/managerMainAppv2', 'static/menu/managerMenu','static/analysis/org/analysis-org', 'static/analysis/report/analysis-report', 'static/analysis/monitoring/analysis-monitoring', 'static/analysis/bd/analysis-bd','static/analysis/trans-analysis','static/payment/partner/add-partner']; - var moduleNames = ['managerMainAppv2', 'listMenuApp','analysisTransaction', 'analysisBD', 'analysisOrg', 'analysisMonitoring', 'analysisReport','addPartnerApp']; + var paths = ['static/boot/managerMainAppv2', 'static/menu/managerMenu','static/analysis/org/analysis-org', 'static/analysis/report/analysis-report', 'static/analysis/monitoring/analysis-monitoring', 'static/analysis/bd/analysis-bd','static/analysis/trans-analysis']; + var moduleNames = ['managerMainAppv2', 'listMenuApp','analysisTransaction', 'analysisBD', 'analysisOrg', 'analysisMonitoring', 'analysisReport']; window.currentUser = user; angular.forEach(user.modules, function (mod) { paths.push(mod.js_path); From f5111d47e28f7cfb14f0c098de92c6cf46961303 Mon Sep 17 00:00:00 2001 From: dulingling Date: Wed, 29 Apr 2020 13:36:05 +0800 Subject: [PATCH 40/40] =?UTF-8?q?Upd:=E4=BF=A1=E7=94=A8=E5=8D=A1=E5=90=88?= =?UTF-8?q?=E8=A7=84=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/impls/ClientManagerImpl.java | 6 +++--- .../templates/pdf/letter_of_offer.pdf | Bin 186807 -> 186831 bytes 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index db524b05b..75f188080 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -466,9 +466,9 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid client.put("show_all_permission", checkBDPermission > 0); if (checkBDPermission > 0) { JSONObject org = orgMapper.findOne(manager.getIntValue("org_id")); - boolean bdRateEditable = client.getIntValue("approve_result") != 1 || - (client.getIntValue("upay_approve_result") !=1 && !client.containsKey("upay_approve_result") && client.getIntValue("upay_approve_result") !=4) - || org.getBooleanValue("rate_editable"); + boolean bdRateEditable = client.getIntValue("approve_result") != 1 || org.getBooleanValue("rate_editable") || + //开起信用卡支付申请,并且申请结果不是:null.新建 1.通过 4.BD已提交资料状态 + ( !clientConfig.getBoolean("enable_card_payment") && !client.containsKey("upay_approve_result") && client.getIntValue("upay_approve_result") !=1 && client.getIntValue("upay_approve_result") !=4); client.put("rate_editable", bdRateEditable); } else { client.put("company_phone", "******"); diff --git a/src/main/resources/templates/pdf/letter_of_offer.pdf b/src/main/resources/templates/pdf/letter_of_offer.pdf index 2aa701a83747f56cb97fad26dcfc00e6285dfcc9..a6a8a6ade7a40a602f0dfebda5fedcbf380e7029 100644 GIT binary patch delta 13588 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

    g#?|v{cNhq(5;~%jqtq4hy*`wv4dYqY zcqg}IXh3_=M(3c=JKc^x52O8%snEL9V%C`?&s>`zs&fy-)`FWO*%^JWC#Rq;T^1Kr zE4MtYKzGq|C>^F1JJ{x&!8v=*X}Adv&kLQo_9R>PKG6J3PpcrXU1c7*$1|S5whrX( z^76Xp_0lMCxBJvj@YMX3-<#WRGanC~xWZDi9|GM!~a zbHrSsoQhVL`-;T2u~J>7z<_`En7*MR~PL2bc2%rgEX z*)%$zKM1w=YIESX7{5^L19KZ zzR|vL7tuNr`Pb$R#0s&aeFK1nw5^pt-)n#_It+6CZjUZ4Jf7CGTHKT6H1`55-E`X4 zoV<^d_qTyB?^ocfPyP>_p&Da0c18Suo$suLdG?yP7gL5lRA&ZDYB1B9`MJ}gN`|Nk z8O7D^#(5*xHi>%oMbu7I)e-nB4uXn;{@k!DA`|XOIZ#~#McZu5-9VTgu(hK-^+6pp zn>gBd(4OLDk39?k2Ew+cqIl-_+6kEeDy!pg!OX00*!pV1O@VPv{0tOUeCnHF=wv!->yon$W=MTW;H0a0 zpW`l*6aleKq|m=Eio(ra%|$MvmtoW>xe?ghKChz#>#5=4)TfX8!z)l8gO&N&_GEVg z@$_~@GYhq*QaobhY)L@cYLLwHe-q8fV?oQ%j?<+1^Zgno;bbot^A;}5Ex z%-p!^S0F+e*Nmi9A3+x>+yCBD7X_MUHb@kE9;?ID$o3#gx`bOuVGo07% zy*3XL6Z8vf`k56?U-%W`Og{iyUPOVc9==$6hxg+B00!eXDj~b%08wPra4X$PFL?;v zERzIBkT~{l9=ia9t}V#JMw(;5H$=5`y4$)rAj0Ts#T+IOsaAEe9u+}rz(_noqw@wn zA_NsstM&s%XO+lx)4z|LJ4CNvpKo8n1WKQSdK&#=S=RlLuo|W0XQWB%b1LD3)@{3G zvIh0c=20c|FQQhnmyUy9gyc3@))>#QSKcGNAH>z$j?LZf6lKP4QrF%v=g2p=itohC zKxDvu{s6ya+caQGE1&0lHoJ)(0wM1wiaY8k6X35z*t@aZtW!0v*`c=WjYR8)iXj2i zl1iBC!W}!!nE&RkZi=syKm3pZ^4Wan#`9{D7yyEuEF7TMX2h{H z%}*e}U7dqv7W+PUDqI86b`^ilATpr_9H%?Q3`EWBU4a}f9aw3^&#JTPLgnl@w1WNF zk$HdPkoczR^~#iTd%HSz2;J%9sy@|pZlX&pfD>lu+cEqQ;*0k;U=ekrBJ|b+O#z=v z-0Y;P0hS_}IMe(F#j=()d8jV!p;Q0`aET`2$X`G%Vl`+e;GXjn8=W@>ob)jp2>E&F zm-B$qXdBB*k`&yY$|yyX{6HUqi;>xan8}w)87^Xxin=^c(F^X+B4U+E3LWps6mpU) z_AG_sjLlq1>|ctQFCt@U&bo8m=6YhOI?7_Vd74EYK{QY8O4CaKtumV|A|)-NB)NhA zEkRWrJS)IP)FeO3$5}==c0M8jXagTZ$(|9dT((0+@3eDuPy-813|4{&$z~x^7lhY^ zMx1=;2gxT7qF1Dx2H?n)2DeI1c3CmwzfXYiW+v)G;!@1^2HIeT@B@uxce^9HV5DvZ z{Vq&$S1&v@R>L~Y z7cU1VFAICx&?JEW|J4zu0Ey%#Mn)Xm<|aH0JZ7eB4D6A42)mLM7}xDfu#PZeagF3ps{y;XgB{(X0Th zN&bJIf&`OLz%kP%RsiNefH{`G^wqDrDzNko7|O+e{ZAAKE2+rDtb26fruHxiHW9>$ zt`sYf5GZ3=U`rh6^7;_%_j$t>D0rh{@!4Oq64DeIJtQmiUo;#sg5>i*v@<4OtSp0j zsd*ZuhueyFnPp>3>7o`wpy

    - +
    - +
    - +
    - +
    - +