diff --git a/backend/cmd/server/wire.go b/backend/cmd/server/wire.go index 7fc648ac3a..634a44884b 100644 --- a/backend/cmd/server/wire.go +++ b/backend/cmd/server/wire.go @@ -16,6 +16,7 @@ import ( "github.com/Wei-Shaw/sub2api/internal/repository" "github.com/Wei-Shaw/sub2api/internal/server" "github.com/Wei-Shaw/sub2api/internal/server/middleware" + "github.com/Wei-Shaw/sub2api/internal/payment" "github.com/Wei-Shaw/sub2api/internal/service" "github.com/google/wire" @@ -35,6 +36,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { // Business layer ProviderSets repository.ProviderSet, service.ProviderSet, + payment.ProviderSet, middleware.ProviderSet, handler.ProviderSet, @@ -95,6 +97,7 @@ func provideCleanup( openAIGateway *service.OpenAIGatewayService, scheduledTestRunner *service.ScheduledTestRunnerService, backupSvc *service.BackupService, + paymentOrderExpiry *service.PaymentOrderExpiryService, ) func() { return func() { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) @@ -237,6 +240,12 @@ func provideCleanup( } return nil }}, + {"PaymentOrderExpiryService", func() error { + if paymentOrderExpiry != nil { + paymentOrderExpiry.Stop() + } + return nil + }}, } infraSteps := []cleanupStep{ diff --git a/backend/cmd/server/wire_gen.go b/backend/cmd/server/wire_gen.go index 7b7ec0e6cf..93c907c674 100644 --- a/backend/cmd/server/wire_gen.go +++ b/backend/cmd/server/wire_gen.go @@ -12,6 +12,7 @@ import ( "github.com/Wei-Shaw/sub2api/internal/config" "github.com/Wei-Shaw/sub2api/internal/handler" "github.com/Wei-Shaw/sub2api/internal/handler/admin" + "github.com/Wei-Shaw/sub2api/internal/payment" "github.com/Wei-Shaw/sub2api/internal/repository" "github.com/Wei-Shaw/sub2api/internal/server" "github.com/Wei-Shaw/sub2api/internal/server/middleware" @@ -49,7 +50,6 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { refreshTokenCache := repository.NewRefreshTokenCache(redisClient) settingRepository := repository.NewSettingRepository(client) groupRepository := repository.NewGroupRepository(client, db) - channelRepository := repository.NewChannelRepository(db) settingService := service.ProvideSettingService(settingRepository, groupRepository, configConfig) emailCache := repository.NewEmailCache(redisClient) emailService := service.NewEmailService(settingRepository, emailCache) @@ -64,7 +64,6 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { userGroupRateRepository := repository.NewUserGroupRateRepository(db) apiKeyCache := repository.NewAPIKeyCache(redisClient) apiKeyService := service.NewAPIKeyService(apiKeyRepository, userRepository, groupRepository, userSubscriptionRepository, userGroupRateRepository, apiKeyCache, configConfig) - apiKeyService.SetRateLimitCacheInvalidator(billingCache) apiKeyAuthCacheInvalidator := service.ProvideAPIKeyAuthCacheInvalidator(apiKeyService) promoService := service.NewPromoService(promoCodeRepository, userRepository, billingCacheService, client, apiKeyAuthCacheInvalidator) subscriptionService := service.NewSubscriptionService(groupRepository, userSubscriptionRepository, billingCacheService, client, configConfig) @@ -82,7 +81,6 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { userHandler := handler.NewUserHandler(userService) apiKeyHandler := handler.NewAPIKeyHandler(apiKeyService) usageLogRepository := repository.NewUsageLogRepository(client, db) - usageBillingRepository := repository.NewUsageBillingRepository(client, db) usageService := service.NewUsageService(usageLogRepository, userRepository, client, apiKeyAuthCacheInvalidator) usageHandler := handler.NewUsageHandler(usageService, apiKeyService) redeemHandler := handler.NewRedeemHandler(redeemService) @@ -110,11 +108,14 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { concurrencyCache := repository.ProvideConcurrencyCache(redisClient, configConfig) concurrencyService := service.ProvideConcurrencyService(concurrencyCache, accountRepository, configConfig) adminUserHandler := admin.NewUserHandler(adminService, concurrencyService) + sessionLimitCache := repository.ProvideSessionLimitCache(redisClient, configConfig) + rpmCache := repository.NewRPMCache(redisClient) + groupCapacityService := service.NewGroupCapacityService(accountRepository, groupRepository, concurrencyService, sessionLimitCache, rpmCache) + groupHandler := admin.NewGroupHandler(adminService, dashboardService, groupCapacityService) claudeOAuthClient := repository.NewClaudeOAuthClient() oAuthService := service.NewOAuthService(proxyRepository, claudeOAuthClient) openAIOAuthClient := repository.NewOpenAIOAuthClient() openAIOAuthService := service.NewOpenAIOAuthService(proxyRepository, openAIOAuthClient) - openAIOAuthService.SetPrivacyClientFactory(privacyClientFactory) geminiOAuthClient := repository.NewGeminiOAuthClient(configConfig) geminiCliCodeAssistClient := repository.NewGeminiCliCodeAssistClient() driveClient := repository.NewGeminiDriveClient() @@ -124,7 +125,6 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { tempUnschedCache := repository.NewTempUnschedCache(redisClient) timeoutCounterCache := repository.NewTimeoutCounterCache(redisClient) geminiTokenCache := repository.NewGeminiTokenCache(redisClient) - oauthRefreshAPI := service.NewOAuthRefreshAPI(accountRepository, geminiTokenCache) compositeTokenCacheInvalidator := service.NewCompositeTokenCacheInvalidator(geminiTokenCache) rateLimitService := service.ProvideRateLimitService(accountRepository, usageLogRepository, configConfig, geminiQuotaService, tempUnschedCache, timeoutCounterCache, settingService, compositeTokenCacheInvalidator) httpUpstream := repository.NewHTTPUpstream(configConfig) @@ -132,23 +132,20 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { antigravityQuotaFetcher := service.NewAntigravityQuotaFetcher(proxyRepository) usageCache := service.NewUsageCache() identityCache := repository.NewIdentityCache(redisClient) - geminiTokenProvider := service.ProvideGeminiTokenProvider(accountRepository, geminiTokenCache, geminiOAuthService, oauthRefreshAPI) - gatewayCache := repository.NewGatewayCache(redisClient) - schedulerOutboxRepository := repository.NewSchedulerOutboxRepository(db) - schedulerSnapshotService := service.ProvideSchedulerSnapshotService(schedulerCache, schedulerOutboxRepository, accountRepository, groupRepository, configConfig) - antigravityTokenProvider := service.ProvideAntigravityTokenProvider(accountRepository, geminiTokenCache, antigravityOAuthService, oauthRefreshAPI, tempUnschedCache) - internal500CounterCache := repository.NewInternal500CounterCache(redisClient) tlsFingerprintProfileRepository := repository.NewTLSFingerprintProfileRepository(client) tlsFingerprintProfileCache := repository.NewTLSFingerprintProfileCache(redisClient) tlsFingerprintProfileService := service.NewTLSFingerprintProfileService(tlsFingerprintProfileRepository, tlsFingerprintProfileCache) accountUsageService := service.NewAccountUsageService(accountRepository, usageLogRepository, claudeUsageFetcher, geminiQuotaService, antigravityQuotaFetcher, usageCache, identityCache, tlsFingerprintProfileService) + oAuthRefreshAPI := service.NewOAuthRefreshAPI(accountRepository, geminiTokenCache) + geminiTokenProvider := service.ProvideGeminiTokenProvider(accountRepository, geminiTokenCache, geminiOAuthService, oAuthRefreshAPI) + gatewayCache := repository.NewGatewayCache(redisClient) + schedulerOutboxRepository := repository.NewSchedulerOutboxRepository(db) + schedulerSnapshotService := service.ProvideSchedulerSnapshotService(schedulerCache, schedulerOutboxRepository, accountRepository, groupRepository, configConfig) + antigravityTokenProvider := service.ProvideAntigravityTokenProvider(accountRepository, geminiTokenCache, antigravityOAuthService, oAuthRefreshAPI, tempUnschedCache) + internal500CounterCache := repository.NewInternal500CounterCache(redisClient) antigravityGatewayService := service.NewAntigravityGatewayService(accountRepository, gatewayCache, schedulerSnapshotService, antigravityTokenProvider, rateLimitService, httpUpstream, settingService, internal500CounterCache, accountUsageService) accountTestService := service.NewAccountTestService(accountRepository, geminiTokenProvider, antigravityGatewayService, httpUpstream, configConfig, tlsFingerprintProfileService) crsSyncService := service.NewCRSSyncService(accountRepository, proxyRepository, oAuthService, openAIOAuthService, geminiOAuthService, configConfig) - sessionLimitCache := repository.ProvideSessionLimitCache(redisClient, configConfig) - rpmCache := repository.NewRPMCache(redisClient) - groupCapacityService := service.NewGroupCapacityService(accountRepository, groupRepository, concurrencyService, sessionLimitCache, rpmCache) - groupHandler := admin.NewGroupHandler(adminService, dashboardService, groupCapacityService) accountHandler := admin.NewAccountHandler(adminService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, rateLimitService, accountUsageService, accountTestService, concurrencyService, crsSyncService, sessionLimitCache, rpmCache, compositeTokenCacheInvalidator) adminAnnouncementHandler := admin.NewAnnouncementHandler(announcementService) dataManagementService := service.NewDataManagementService() @@ -165,6 +162,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { adminRedeemHandler := admin.NewRedeemHandler(adminService, redeemService) promoHandler := admin.NewPromoHandler(promoService) opsRepository := repository.NewOpsRepository(db) + usageBillingRepository := repository.NewUsageBillingRepository(client, db) pricingRemoteClient := repository.ProvidePricingRemoteClient(configConfig) pricingService, err := service.ProvidePricingService(configConfig, pricingRemoteClient) if err != nil { @@ -173,12 +171,13 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { billingService := service.NewBillingService(configConfig, pricingService) identityService := service.NewIdentityService(identityCache) deferredService := service.ProvideDeferredService(accountRepository, timingWheelService) - claudeTokenProvider := service.ProvideClaudeTokenProvider(accountRepository, geminiTokenCache, oAuthService, oauthRefreshAPI) + claudeTokenProvider := service.ProvideClaudeTokenProvider(accountRepository, geminiTokenCache, oAuthService, oAuthRefreshAPI) digestSessionStore := service.NewDigestSessionStore() + channelRepository := repository.NewChannelRepository(db) channelService := service.NewChannelService(channelRepository, apiKeyAuthCacheInvalidator) modelPricingResolver := service.NewModelPricingResolver(channelService, billingService) gatewayService := service.NewGatewayService(accountRepository, groupRepository, usageLogRepository, usageBillingRepository, userRepository, userSubscriptionRepository, userGroupRateRepository, gatewayCache, configConfig, schedulerSnapshotService, concurrencyService, billingService, rateLimitService, billingCacheService, identityService, httpUpstream, deferredService, claudeTokenProvider, sessionLimitCache, rpmCache, digestSessionStore, settingService, tlsFingerprintProfileService, channelService, modelPricingResolver) - openAITokenProvider := service.ProvideOpenAITokenProvider(accountRepository, geminiTokenCache, openAIOAuthService, oauthRefreshAPI) + openAITokenProvider := service.ProvideOpenAITokenProvider(accountRepository, geminiTokenCache, openAIOAuthService, oAuthRefreshAPI) openAIGatewayService := service.NewOpenAIGatewayService(accountRepository, usageLogRepository, usageBillingRepository, userRepository, userSubscriptionRepository, userGroupRateRepository, gatewayCache, configConfig, schedulerSnapshotService, concurrencyService, billingService, rateLimitService, billingCacheService, httpUpstream, deferredService, openAITokenProvider, modelPricingResolver, channelService) geminiMessagesCompatService := service.NewGeminiMessagesCompatService(accountRepository, groupRepository, gatewayCache, schedulerSnapshotService, geminiTokenProvider, rateLimitService, httpUpstream, antigravityGatewayService, configConfig) opsSystemLogSink := service.ProvideOpsSystemLogSink(opsRepository) @@ -211,7 +210,14 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { scheduledTestService := service.ProvideScheduledTestService(scheduledTestPlanRepository, scheduledTestResultRepository) scheduledTestHandler := admin.NewScheduledTestHandler(scheduledTestService) channelHandler := admin.NewChannelHandler(channelService, billingService) - adminHandlers := handler.ProvideAdminHandlers(dashboardHandler, adminUserHandler, groupHandler, accountHandler, adminAnnouncementHandler, dataManagementHandler, backupHandler, oAuthHandler, openAIOAuthHandler, geminiOAuthHandler, antigravityOAuthHandler, proxyHandler, adminRedeemHandler, promoHandler, settingHandler, opsHandler, systemHandler, adminSubscriptionHandler, adminUsageHandler, userAttributeHandler, errorPassthroughHandler, tlsFingerprintProfileHandler, adminAPIKeyHandler, scheduledTestHandler, channelHandler) + registry := payment.ProvideRegistry() + encryptionKey := payment.ProvideEncryptionKey(configConfig) + defaultLoadBalancer := payment.ProvideDefaultLoadBalancer(client, encryptionKey) + paymentConfigService := service.ProvidePaymentConfigService(client, settingRepository, encryptionKey) + paymentService := service.NewPaymentService(client, registry, defaultLoadBalancer, redeemService, subscriptionService, paymentConfigService, userRepository, groupRepository) + paymentOrderExpiryService := service.ProvidePaymentOrderExpiryService(paymentService) + paymentHandler := admin.NewPaymentHandler(paymentService, paymentConfigService) + adminHandlers := handler.ProvideAdminHandlers(dashboardHandler, adminUserHandler, groupHandler, accountHandler, adminAnnouncementHandler, dataManagementHandler, backupHandler, oAuthHandler, openAIOAuthHandler, geminiOAuthHandler, antigravityOAuthHandler, proxyHandler, adminRedeemHandler, promoHandler, settingHandler, opsHandler, systemHandler, adminSubscriptionHandler, adminUsageHandler, userAttributeHandler, errorPassthroughHandler, tlsFingerprintProfileHandler, adminAPIKeyHandler, scheduledTestHandler, channelHandler, paymentHandler) usageRecordWorkerPool := service.NewUsageRecordWorkerPool(configConfig) userMsgQueueCache := repository.NewUserMsgQueueCache(redisClient) userMessageQueueService := service.ProvideUserMessageQueueService(userMsgQueueCache, rpmCache, configConfig) @@ -219,9 +225,11 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { openAIGatewayHandler := handler.NewOpenAIGatewayHandler(openAIGatewayService, concurrencyService, billingCacheService, apiKeyService, usageRecordWorkerPool, errorPassthroughService, configConfig) handlerSettingHandler := handler.ProvideSettingHandler(settingService, buildInfo) totpHandler := handler.NewTotpHandler(totpService) + handlerPaymentHandler := handler.NewPaymentHandler(paymentService, paymentConfigService, channelService) + paymentWebhookHandler := handler.NewPaymentWebhookHandler(paymentService, registry) idempotencyCoordinator := service.ProvideIdempotencyCoordinator(idempotencyRepository, configConfig) idempotencyCleanupService := service.ProvideIdempotencyCleanupService(idempotencyRepository, configConfig) - handlers := handler.ProvideHandlers(authHandler, userHandler, apiKeyHandler, usageHandler, redeemHandler, subscriptionHandler, announcementHandler, adminHandlers, gatewayHandler, openAIGatewayHandler, handlerSettingHandler, totpHandler, idempotencyCoordinator, idempotencyCleanupService) + handlers := handler.ProvideHandlers(authHandler, userHandler, apiKeyHandler, usageHandler, redeemHandler, subscriptionHandler, announcementHandler, adminHandlers, gatewayHandler, openAIGatewayHandler, handlerSettingHandler, totpHandler, handlerPaymentHandler, paymentWebhookHandler, idempotencyCoordinator, idempotencyCleanupService) jwtAuthMiddleware := middleware.NewJWTAuthMiddleware(authService, userService) adminAuthMiddleware := middleware.NewAdminAuthMiddleware(authService, userService, settingService) apiKeyAuthMiddleware := middleware.NewAPIKeyAuthMiddleware(apiKeyService, subscriptionService, configConfig) @@ -232,11 +240,11 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { opsAlertEvaluatorService := service.ProvideOpsAlertEvaluatorService(opsService, opsRepository, emailService, redisClient, configConfig) opsCleanupService := service.ProvideOpsCleanupService(opsRepository, db, redisClient, configConfig) opsScheduledReportService := service.ProvideOpsScheduledReportService(opsService, userService, emailService, redisClient, configConfig) - tokenRefreshService := service.ProvideTokenRefreshService(accountRepository, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, compositeTokenCacheInvalidator, schedulerCache, configConfig, tempUnschedCache, privacyClientFactory, proxyRepository, oauthRefreshAPI) + tokenRefreshService := service.ProvideTokenRefreshService(accountRepository, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, compositeTokenCacheInvalidator, schedulerCache, configConfig, tempUnschedCache, privacyClientFactory, proxyRepository, oAuthRefreshAPI) accountExpiryService := service.ProvideAccountExpiryService(accountRepository) subscriptionExpiryService := service.ProvideSubscriptionExpiryService(userSubscriptionRepository) scheduledTestRunnerService := service.ProvideScheduledTestRunnerService(scheduledTestPlanRepository, scheduledTestService, accountTestService, rateLimitService, configConfig) - v := provideCleanup(client, redisClient, opsMetricsCollector, opsAggregationService, opsAlertEvaluatorService, opsCleanupService, opsScheduledReportService, opsSystemLogSink, schedulerSnapshotService, tokenRefreshService, accountExpiryService, subscriptionExpiryService, usageCleanupService, idempotencyCleanupService, pricingService, emailQueueService, billingCacheService, usageRecordWorkerPool, subscriptionService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, openAIGatewayService, scheduledTestRunnerService, backupService) + v := provideCleanup(client, redisClient, opsMetricsCollector, opsAggregationService, opsAlertEvaluatorService, opsCleanupService, opsScheduledReportService, opsSystemLogSink, schedulerSnapshotService, tokenRefreshService, accountExpiryService, subscriptionExpiryService, usageCleanupService, idempotencyCleanupService, pricingService, emailQueueService, billingCacheService, usageRecordWorkerPool, subscriptionService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, openAIGatewayService, scheduledTestRunnerService, backupService, paymentOrderExpiryService) application := &Application{ Server: httpServer, Cleanup: v, @@ -289,6 +297,7 @@ func provideCleanup( openAIGateway *service.OpenAIGatewayService, scheduledTestRunner *service.ScheduledTestRunnerService, backupSvc *service.BackupService, + paymentOrderExpiry *service.PaymentOrderExpiryService, ) func() { return func() { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) @@ -424,6 +433,12 @@ func provideCleanup( } return nil }}, + {"PaymentOrderExpiryService", func() error { + if paymentOrderExpiry != nil { + paymentOrderExpiry.Stop() + } + return nil + }}, } infraSteps := []cleanupStep{ diff --git a/backend/ent/client.go b/backend/ent/client.go index 4129d6c5fe..3da7acf892 100644 --- a/backend/ent/client.go +++ b/backend/ent/client.go @@ -23,12 +23,16 @@ import ( "github.com/Wei-Shaw/sub2api/ent/errorpassthroughrule" "github.com/Wei-Shaw/sub2api/ent/group" "github.com/Wei-Shaw/sub2api/ent/idempotencyrecord" + "github.com/Wei-Shaw/sub2api/ent/paymentauditlog" + "github.com/Wei-Shaw/sub2api/ent/paymentorder" + "github.com/Wei-Shaw/sub2api/ent/paymentproviderinstance" "github.com/Wei-Shaw/sub2api/ent/promocode" "github.com/Wei-Shaw/sub2api/ent/promocodeusage" "github.com/Wei-Shaw/sub2api/ent/proxy" "github.com/Wei-Shaw/sub2api/ent/redeemcode" "github.com/Wei-Shaw/sub2api/ent/securitysecret" "github.com/Wei-Shaw/sub2api/ent/setting" + "github.com/Wei-Shaw/sub2api/ent/subscriptionplan" "github.com/Wei-Shaw/sub2api/ent/tlsfingerprintprofile" "github.com/Wei-Shaw/sub2api/ent/usagecleanuptask" "github.com/Wei-Shaw/sub2api/ent/usagelog" @@ -62,6 +66,12 @@ type Client struct { Group *GroupClient // IdempotencyRecord is the client for interacting with the IdempotencyRecord builders. IdempotencyRecord *IdempotencyRecordClient + // PaymentAuditLog is the client for interacting with the PaymentAuditLog builders. + PaymentAuditLog *PaymentAuditLogClient + // PaymentOrder is the client for interacting with the PaymentOrder builders. + PaymentOrder *PaymentOrderClient + // PaymentProviderInstance is the client for interacting with the PaymentProviderInstance builders. + PaymentProviderInstance *PaymentProviderInstanceClient // PromoCode is the client for interacting with the PromoCode builders. PromoCode *PromoCodeClient // PromoCodeUsage is the client for interacting with the PromoCodeUsage builders. @@ -74,6 +84,8 @@ type Client struct { SecuritySecret *SecuritySecretClient // Setting is the client for interacting with the Setting builders. Setting *SettingClient + // SubscriptionPlan is the client for interacting with the SubscriptionPlan builders. + SubscriptionPlan *SubscriptionPlanClient // TLSFingerprintProfile is the client for interacting with the TLSFingerprintProfile builders. TLSFingerprintProfile *TLSFingerprintProfileClient // UsageCleanupTask is the client for interacting with the UsageCleanupTask builders. @@ -109,12 +121,16 @@ func (c *Client) init() { c.ErrorPassthroughRule = NewErrorPassthroughRuleClient(c.config) c.Group = NewGroupClient(c.config) c.IdempotencyRecord = NewIdempotencyRecordClient(c.config) + c.PaymentAuditLog = NewPaymentAuditLogClient(c.config) + c.PaymentOrder = NewPaymentOrderClient(c.config) + c.PaymentProviderInstance = NewPaymentProviderInstanceClient(c.config) c.PromoCode = NewPromoCodeClient(c.config) c.PromoCodeUsage = NewPromoCodeUsageClient(c.config) c.Proxy = NewProxyClient(c.config) c.RedeemCode = NewRedeemCodeClient(c.config) c.SecuritySecret = NewSecuritySecretClient(c.config) c.Setting = NewSettingClient(c.config) + c.SubscriptionPlan = NewSubscriptionPlanClient(c.config) c.TLSFingerprintProfile = NewTLSFingerprintProfileClient(c.config) c.UsageCleanupTask = NewUsageCleanupTaskClient(c.config) c.UsageLog = NewUsageLogClient(c.config) @@ -223,12 +239,16 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { ErrorPassthroughRule: NewErrorPassthroughRuleClient(cfg), Group: NewGroupClient(cfg), IdempotencyRecord: NewIdempotencyRecordClient(cfg), + PaymentAuditLog: NewPaymentAuditLogClient(cfg), + PaymentOrder: NewPaymentOrderClient(cfg), + PaymentProviderInstance: NewPaymentProviderInstanceClient(cfg), PromoCode: NewPromoCodeClient(cfg), PromoCodeUsage: NewPromoCodeUsageClient(cfg), Proxy: NewProxyClient(cfg), RedeemCode: NewRedeemCodeClient(cfg), SecuritySecret: NewSecuritySecretClient(cfg), Setting: NewSettingClient(cfg), + SubscriptionPlan: NewSubscriptionPlanClient(cfg), TLSFingerprintProfile: NewTLSFingerprintProfileClient(cfg), UsageCleanupTask: NewUsageCleanupTaskClient(cfg), UsageLog: NewUsageLogClient(cfg), @@ -264,12 +284,16 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) ErrorPassthroughRule: NewErrorPassthroughRuleClient(cfg), Group: NewGroupClient(cfg), IdempotencyRecord: NewIdempotencyRecordClient(cfg), + PaymentAuditLog: NewPaymentAuditLogClient(cfg), + PaymentOrder: NewPaymentOrderClient(cfg), + PaymentProviderInstance: NewPaymentProviderInstanceClient(cfg), PromoCode: NewPromoCodeClient(cfg), PromoCodeUsage: NewPromoCodeUsageClient(cfg), Proxy: NewProxyClient(cfg), RedeemCode: NewRedeemCodeClient(cfg), SecuritySecret: NewSecuritySecretClient(cfg), Setting: NewSettingClient(cfg), + SubscriptionPlan: NewSubscriptionPlanClient(cfg), TLSFingerprintProfile: NewTLSFingerprintProfileClient(cfg), UsageCleanupTask: NewUsageCleanupTaskClient(cfg), UsageLog: NewUsageLogClient(cfg), @@ -308,10 +332,11 @@ func (c *Client) Close() error { func (c *Client) Use(hooks ...Hook) { for _, n := range []interface{ Use(...Hook) }{ c.APIKey, c.Account, c.AccountGroup, c.Announcement, c.AnnouncementRead, - c.ErrorPassthroughRule, c.Group, c.IdempotencyRecord, c.PromoCode, + c.ErrorPassthroughRule, c.Group, c.IdempotencyRecord, c.PaymentAuditLog, + c.PaymentOrder, c.PaymentProviderInstance, c.PromoCode, c.PromoCodeUsage, c.Proxy, c.RedeemCode, c.SecuritySecret, c.Setting, - c.TLSFingerprintProfile, c.UsageCleanupTask, c.UsageLog, c.User, - c.UserAllowedGroup, c.UserAttributeDefinition, c.UserAttributeValue, + c.SubscriptionPlan, c.TLSFingerprintProfile, c.UsageCleanupTask, c.UsageLog, + c.User, c.UserAllowedGroup, c.UserAttributeDefinition, c.UserAttributeValue, c.UserSubscription, } { n.Use(hooks...) @@ -323,10 +348,11 @@ func (c *Client) Use(hooks ...Hook) { func (c *Client) Intercept(interceptors ...Interceptor) { for _, n := range []interface{ Intercept(...Interceptor) }{ c.APIKey, c.Account, c.AccountGroup, c.Announcement, c.AnnouncementRead, - c.ErrorPassthroughRule, c.Group, c.IdempotencyRecord, c.PromoCode, + c.ErrorPassthroughRule, c.Group, c.IdempotencyRecord, c.PaymentAuditLog, + c.PaymentOrder, c.PaymentProviderInstance, c.PromoCode, c.PromoCodeUsage, c.Proxy, c.RedeemCode, c.SecuritySecret, c.Setting, - c.TLSFingerprintProfile, c.UsageCleanupTask, c.UsageLog, c.User, - c.UserAllowedGroup, c.UserAttributeDefinition, c.UserAttributeValue, + c.SubscriptionPlan, c.TLSFingerprintProfile, c.UsageCleanupTask, c.UsageLog, + c.User, c.UserAllowedGroup, c.UserAttributeDefinition, c.UserAttributeValue, c.UserSubscription, } { n.Intercept(interceptors...) @@ -352,6 +378,12 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) { return c.Group.mutate(ctx, m) case *IdempotencyRecordMutation: return c.IdempotencyRecord.mutate(ctx, m) + case *PaymentAuditLogMutation: + return c.PaymentAuditLog.mutate(ctx, m) + case *PaymentOrderMutation: + return c.PaymentOrder.mutate(ctx, m) + case *PaymentProviderInstanceMutation: + return c.PaymentProviderInstance.mutate(ctx, m) case *PromoCodeMutation: return c.PromoCode.mutate(ctx, m) case *PromoCodeUsageMutation: @@ -364,6 +396,8 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) { return c.SecuritySecret.mutate(ctx, m) case *SettingMutation: return c.Setting.mutate(ctx, m) + case *SubscriptionPlanMutation: + return c.SubscriptionPlan.mutate(ctx, m) case *TLSFingerprintProfileMutation: return c.TLSFingerprintProfile.mutate(ctx, m) case *UsageCleanupTaskMutation: @@ -1726,6 +1760,421 @@ func (c *IdempotencyRecordClient) mutate(ctx context.Context, m *IdempotencyReco } } +// PaymentAuditLogClient is a client for the PaymentAuditLog schema. +type PaymentAuditLogClient struct { + config +} + +// NewPaymentAuditLogClient returns a client for the PaymentAuditLog from the given config. +func NewPaymentAuditLogClient(c config) *PaymentAuditLogClient { + return &PaymentAuditLogClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `paymentauditlog.Hooks(f(g(h())))`. +func (c *PaymentAuditLogClient) Use(hooks ...Hook) { + c.hooks.PaymentAuditLog = append(c.hooks.PaymentAuditLog, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `paymentauditlog.Intercept(f(g(h())))`. +func (c *PaymentAuditLogClient) Intercept(interceptors ...Interceptor) { + c.inters.PaymentAuditLog = append(c.inters.PaymentAuditLog, interceptors...) +} + +// Create returns a builder for creating a PaymentAuditLog entity. +func (c *PaymentAuditLogClient) Create() *PaymentAuditLogCreate { + mutation := newPaymentAuditLogMutation(c.config, OpCreate) + return &PaymentAuditLogCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of PaymentAuditLog entities. +func (c *PaymentAuditLogClient) CreateBulk(builders ...*PaymentAuditLogCreate) *PaymentAuditLogCreateBulk { + return &PaymentAuditLogCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *PaymentAuditLogClient) MapCreateBulk(slice any, setFunc func(*PaymentAuditLogCreate, int)) *PaymentAuditLogCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &PaymentAuditLogCreateBulk{err: fmt.Errorf("calling to PaymentAuditLogClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*PaymentAuditLogCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &PaymentAuditLogCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for PaymentAuditLog. +func (c *PaymentAuditLogClient) Update() *PaymentAuditLogUpdate { + mutation := newPaymentAuditLogMutation(c.config, OpUpdate) + return &PaymentAuditLogUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *PaymentAuditLogClient) UpdateOne(_m *PaymentAuditLog) *PaymentAuditLogUpdateOne { + mutation := newPaymentAuditLogMutation(c.config, OpUpdateOne, withPaymentAuditLog(_m)) + return &PaymentAuditLogUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *PaymentAuditLogClient) UpdateOneID(id int64) *PaymentAuditLogUpdateOne { + mutation := newPaymentAuditLogMutation(c.config, OpUpdateOne, withPaymentAuditLogID(id)) + return &PaymentAuditLogUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for PaymentAuditLog. +func (c *PaymentAuditLogClient) Delete() *PaymentAuditLogDelete { + mutation := newPaymentAuditLogMutation(c.config, OpDelete) + return &PaymentAuditLogDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *PaymentAuditLogClient) DeleteOne(_m *PaymentAuditLog) *PaymentAuditLogDeleteOne { + return c.DeleteOneID(_m.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *PaymentAuditLogClient) DeleteOneID(id int64) *PaymentAuditLogDeleteOne { + builder := c.Delete().Where(paymentauditlog.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &PaymentAuditLogDeleteOne{builder} +} + +// Query returns a query builder for PaymentAuditLog. +func (c *PaymentAuditLogClient) Query() *PaymentAuditLogQuery { + return &PaymentAuditLogQuery{ + config: c.config, + ctx: &QueryContext{Type: TypePaymentAuditLog}, + inters: c.Interceptors(), + } +} + +// Get returns a PaymentAuditLog entity by its id. +func (c *PaymentAuditLogClient) Get(ctx context.Context, id int64) (*PaymentAuditLog, error) { + return c.Query().Where(paymentauditlog.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *PaymentAuditLogClient) GetX(ctx context.Context, id int64) *PaymentAuditLog { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// Hooks returns the client hooks. +func (c *PaymentAuditLogClient) Hooks() []Hook { + return c.hooks.PaymentAuditLog +} + +// Interceptors returns the client interceptors. +func (c *PaymentAuditLogClient) Interceptors() []Interceptor { + return c.inters.PaymentAuditLog +} + +func (c *PaymentAuditLogClient) mutate(ctx context.Context, m *PaymentAuditLogMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&PaymentAuditLogCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&PaymentAuditLogUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&PaymentAuditLogUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&PaymentAuditLogDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown PaymentAuditLog mutation op: %q", m.Op()) + } +} + +// PaymentOrderClient is a client for the PaymentOrder schema. +type PaymentOrderClient struct { + config +} + +// NewPaymentOrderClient returns a client for the PaymentOrder from the given config. +func NewPaymentOrderClient(c config) *PaymentOrderClient { + return &PaymentOrderClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `paymentorder.Hooks(f(g(h())))`. +func (c *PaymentOrderClient) Use(hooks ...Hook) { + c.hooks.PaymentOrder = append(c.hooks.PaymentOrder, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `paymentorder.Intercept(f(g(h())))`. +func (c *PaymentOrderClient) Intercept(interceptors ...Interceptor) { + c.inters.PaymentOrder = append(c.inters.PaymentOrder, interceptors...) +} + +// Create returns a builder for creating a PaymentOrder entity. +func (c *PaymentOrderClient) Create() *PaymentOrderCreate { + mutation := newPaymentOrderMutation(c.config, OpCreate) + return &PaymentOrderCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of PaymentOrder entities. +func (c *PaymentOrderClient) CreateBulk(builders ...*PaymentOrderCreate) *PaymentOrderCreateBulk { + return &PaymentOrderCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *PaymentOrderClient) MapCreateBulk(slice any, setFunc func(*PaymentOrderCreate, int)) *PaymentOrderCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &PaymentOrderCreateBulk{err: fmt.Errorf("calling to PaymentOrderClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*PaymentOrderCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &PaymentOrderCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for PaymentOrder. +func (c *PaymentOrderClient) Update() *PaymentOrderUpdate { + mutation := newPaymentOrderMutation(c.config, OpUpdate) + return &PaymentOrderUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *PaymentOrderClient) UpdateOne(_m *PaymentOrder) *PaymentOrderUpdateOne { + mutation := newPaymentOrderMutation(c.config, OpUpdateOne, withPaymentOrder(_m)) + return &PaymentOrderUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *PaymentOrderClient) UpdateOneID(id int64) *PaymentOrderUpdateOne { + mutation := newPaymentOrderMutation(c.config, OpUpdateOne, withPaymentOrderID(id)) + return &PaymentOrderUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for PaymentOrder. +func (c *PaymentOrderClient) Delete() *PaymentOrderDelete { + mutation := newPaymentOrderMutation(c.config, OpDelete) + return &PaymentOrderDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *PaymentOrderClient) DeleteOne(_m *PaymentOrder) *PaymentOrderDeleteOne { + return c.DeleteOneID(_m.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *PaymentOrderClient) DeleteOneID(id int64) *PaymentOrderDeleteOne { + builder := c.Delete().Where(paymentorder.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &PaymentOrderDeleteOne{builder} +} + +// Query returns a query builder for PaymentOrder. +func (c *PaymentOrderClient) Query() *PaymentOrderQuery { + return &PaymentOrderQuery{ + config: c.config, + ctx: &QueryContext{Type: TypePaymentOrder}, + inters: c.Interceptors(), + } +} + +// Get returns a PaymentOrder entity by its id. +func (c *PaymentOrderClient) Get(ctx context.Context, id int64) (*PaymentOrder, error) { + return c.Query().Where(paymentorder.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *PaymentOrderClient) GetX(ctx context.Context, id int64) *PaymentOrder { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QueryUser queries the user edge of a PaymentOrder. +func (c *PaymentOrderClient) QueryUser(_m *PaymentOrder) *UserQuery { + query := (&UserClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := _m.ID + step := sqlgraph.NewStep( + sqlgraph.From(paymentorder.Table, paymentorder.FieldID, id), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, paymentorder.UserTable, paymentorder.UserColumn), + ) + fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *PaymentOrderClient) Hooks() []Hook { + return c.hooks.PaymentOrder +} + +// Interceptors returns the client interceptors. +func (c *PaymentOrderClient) Interceptors() []Interceptor { + return c.inters.PaymentOrder +} + +func (c *PaymentOrderClient) mutate(ctx context.Context, m *PaymentOrderMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&PaymentOrderCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&PaymentOrderUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&PaymentOrderUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&PaymentOrderDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown PaymentOrder mutation op: %q", m.Op()) + } +} + +// PaymentProviderInstanceClient is a client for the PaymentProviderInstance schema. +type PaymentProviderInstanceClient struct { + config +} + +// NewPaymentProviderInstanceClient returns a client for the PaymentProviderInstance from the given config. +func NewPaymentProviderInstanceClient(c config) *PaymentProviderInstanceClient { + return &PaymentProviderInstanceClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `paymentproviderinstance.Hooks(f(g(h())))`. +func (c *PaymentProviderInstanceClient) Use(hooks ...Hook) { + c.hooks.PaymentProviderInstance = append(c.hooks.PaymentProviderInstance, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `paymentproviderinstance.Intercept(f(g(h())))`. +func (c *PaymentProviderInstanceClient) Intercept(interceptors ...Interceptor) { + c.inters.PaymentProviderInstance = append(c.inters.PaymentProviderInstance, interceptors...) +} + +// Create returns a builder for creating a PaymentProviderInstance entity. +func (c *PaymentProviderInstanceClient) Create() *PaymentProviderInstanceCreate { + mutation := newPaymentProviderInstanceMutation(c.config, OpCreate) + return &PaymentProviderInstanceCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of PaymentProviderInstance entities. +func (c *PaymentProviderInstanceClient) CreateBulk(builders ...*PaymentProviderInstanceCreate) *PaymentProviderInstanceCreateBulk { + return &PaymentProviderInstanceCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *PaymentProviderInstanceClient) MapCreateBulk(slice any, setFunc func(*PaymentProviderInstanceCreate, int)) *PaymentProviderInstanceCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &PaymentProviderInstanceCreateBulk{err: fmt.Errorf("calling to PaymentProviderInstanceClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*PaymentProviderInstanceCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &PaymentProviderInstanceCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for PaymentProviderInstance. +func (c *PaymentProviderInstanceClient) Update() *PaymentProviderInstanceUpdate { + mutation := newPaymentProviderInstanceMutation(c.config, OpUpdate) + return &PaymentProviderInstanceUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *PaymentProviderInstanceClient) UpdateOne(_m *PaymentProviderInstance) *PaymentProviderInstanceUpdateOne { + mutation := newPaymentProviderInstanceMutation(c.config, OpUpdateOne, withPaymentProviderInstance(_m)) + return &PaymentProviderInstanceUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *PaymentProviderInstanceClient) UpdateOneID(id int64) *PaymentProviderInstanceUpdateOne { + mutation := newPaymentProviderInstanceMutation(c.config, OpUpdateOne, withPaymentProviderInstanceID(id)) + return &PaymentProviderInstanceUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for PaymentProviderInstance. +func (c *PaymentProviderInstanceClient) Delete() *PaymentProviderInstanceDelete { + mutation := newPaymentProviderInstanceMutation(c.config, OpDelete) + return &PaymentProviderInstanceDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *PaymentProviderInstanceClient) DeleteOne(_m *PaymentProviderInstance) *PaymentProviderInstanceDeleteOne { + return c.DeleteOneID(_m.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *PaymentProviderInstanceClient) DeleteOneID(id int64) *PaymentProviderInstanceDeleteOne { + builder := c.Delete().Where(paymentproviderinstance.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &PaymentProviderInstanceDeleteOne{builder} +} + +// Query returns a query builder for PaymentProviderInstance. +func (c *PaymentProviderInstanceClient) Query() *PaymentProviderInstanceQuery { + return &PaymentProviderInstanceQuery{ + config: c.config, + ctx: &QueryContext{Type: TypePaymentProviderInstance}, + inters: c.Interceptors(), + } +} + +// Get returns a PaymentProviderInstance entity by its id. +func (c *PaymentProviderInstanceClient) Get(ctx context.Context, id int64) (*PaymentProviderInstance, error) { + return c.Query().Where(paymentproviderinstance.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *PaymentProviderInstanceClient) GetX(ctx context.Context, id int64) *PaymentProviderInstance { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// Hooks returns the client hooks. +func (c *PaymentProviderInstanceClient) Hooks() []Hook { + return c.hooks.PaymentProviderInstance +} + +// Interceptors returns the client interceptors. +func (c *PaymentProviderInstanceClient) Interceptors() []Interceptor { + return c.inters.PaymentProviderInstance +} + +func (c *PaymentProviderInstanceClient) mutate(ctx context.Context, m *PaymentProviderInstanceMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&PaymentProviderInstanceCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&PaymentProviderInstanceUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&PaymentProviderInstanceUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&PaymentProviderInstanceDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown PaymentProviderInstance mutation op: %q", m.Op()) + } +} + // PromoCodeClient is a client for the PromoCode schema. type PromoCodeClient struct { config @@ -2622,6 +3071,139 @@ func (c *SettingClient) mutate(ctx context.Context, m *SettingMutation) (Value, } } +// SubscriptionPlanClient is a client for the SubscriptionPlan schema. +type SubscriptionPlanClient struct { + config +} + +// NewSubscriptionPlanClient returns a client for the SubscriptionPlan from the given config. +func NewSubscriptionPlanClient(c config) *SubscriptionPlanClient { + return &SubscriptionPlanClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `subscriptionplan.Hooks(f(g(h())))`. +func (c *SubscriptionPlanClient) Use(hooks ...Hook) { + c.hooks.SubscriptionPlan = append(c.hooks.SubscriptionPlan, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `subscriptionplan.Intercept(f(g(h())))`. +func (c *SubscriptionPlanClient) Intercept(interceptors ...Interceptor) { + c.inters.SubscriptionPlan = append(c.inters.SubscriptionPlan, interceptors...) +} + +// Create returns a builder for creating a SubscriptionPlan entity. +func (c *SubscriptionPlanClient) Create() *SubscriptionPlanCreate { + mutation := newSubscriptionPlanMutation(c.config, OpCreate) + return &SubscriptionPlanCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of SubscriptionPlan entities. +func (c *SubscriptionPlanClient) CreateBulk(builders ...*SubscriptionPlanCreate) *SubscriptionPlanCreateBulk { + return &SubscriptionPlanCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *SubscriptionPlanClient) MapCreateBulk(slice any, setFunc func(*SubscriptionPlanCreate, int)) *SubscriptionPlanCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &SubscriptionPlanCreateBulk{err: fmt.Errorf("calling to SubscriptionPlanClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*SubscriptionPlanCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &SubscriptionPlanCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for SubscriptionPlan. +func (c *SubscriptionPlanClient) Update() *SubscriptionPlanUpdate { + mutation := newSubscriptionPlanMutation(c.config, OpUpdate) + return &SubscriptionPlanUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *SubscriptionPlanClient) UpdateOne(_m *SubscriptionPlan) *SubscriptionPlanUpdateOne { + mutation := newSubscriptionPlanMutation(c.config, OpUpdateOne, withSubscriptionPlan(_m)) + return &SubscriptionPlanUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *SubscriptionPlanClient) UpdateOneID(id int64) *SubscriptionPlanUpdateOne { + mutation := newSubscriptionPlanMutation(c.config, OpUpdateOne, withSubscriptionPlanID(id)) + return &SubscriptionPlanUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for SubscriptionPlan. +func (c *SubscriptionPlanClient) Delete() *SubscriptionPlanDelete { + mutation := newSubscriptionPlanMutation(c.config, OpDelete) + return &SubscriptionPlanDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *SubscriptionPlanClient) DeleteOne(_m *SubscriptionPlan) *SubscriptionPlanDeleteOne { + return c.DeleteOneID(_m.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *SubscriptionPlanClient) DeleteOneID(id int64) *SubscriptionPlanDeleteOne { + builder := c.Delete().Where(subscriptionplan.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &SubscriptionPlanDeleteOne{builder} +} + +// Query returns a query builder for SubscriptionPlan. +func (c *SubscriptionPlanClient) Query() *SubscriptionPlanQuery { + return &SubscriptionPlanQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeSubscriptionPlan}, + inters: c.Interceptors(), + } +} + +// Get returns a SubscriptionPlan entity by its id. +func (c *SubscriptionPlanClient) Get(ctx context.Context, id int64) (*SubscriptionPlan, error) { + return c.Query().Where(subscriptionplan.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *SubscriptionPlanClient) GetX(ctx context.Context, id int64) *SubscriptionPlan { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// Hooks returns the client hooks. +func (c *SubscriptionPlanClient) Hooks() []Hook { + return c.hooks.SubscriptionPlan +} + +// Interceptors returns the client interceptors. +func (c *SubscriptionPlanClient) Interceptors() []Interceptor { + return c.inters.SubscriptionPlan +} + +func (c *SubscriptionPlanClient) mutate(ctx context.Context, m *SubscriptionPlanMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&SubscriptionPlanCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&SubscriptionPlanUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&SubscriptionPlanUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&SubscriptionPlanDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown SubscriptionPlan mutation op: %q", m.Op()) + } +} + // TLSFingerprintProfileClient is a client for the TLSFingerprintProfile schema. type TLSFingerprintProfileClient struct { config @@ -3353,6 +3935,22 @@ func (c *UserClient) QueryPromoCodeUsages(_m *User) *PromoCodeUsageQuery { return query } +// QueryPaymentOrders queries the payment_orders edge of a User. +func (c *UserClient) QueryPaymentOrders(_m *User) *PaymentOrderQuery { + query := (&PaymentOrderClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := _m.ID + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, id), + sqlgraph.To(paymentorder.Table, paymentorder.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, user.PaymentOrdersTable, user.PaymentOrdersColumn), + ) + fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) + return fromV, nil + } + return query +} + // QueryUserAllowedGroups queries the user_allowed_groups edge of a User. func (c *UserClient) QueryUserAllowedGroups(_m *User) *UserAllowedGroupQuery { query := (&UserAllowedGroupClient{config: c.config}).Query() @@ -4031,17 +4629,19 @@ func (c *UserSubscriptionClient) mutate(ctx context.Context, m *UserSubscription type ( hooks struct { APIKey, Account, AccountGroup, Announcement, AnnouncementRead, - ErrorPassthroughRule, Group, IdempotencyRecord, PromoCode, PromoCodeUsage, - Proxy, RedeemCode, SecuritySecret, Setting, TLSFingerprintProfile, - UsageCleanupTask, UsageLog, User, UserAllowedGroup, UserAttributeDefinition, - UserAttributeValue, UserSubscription []ent.Hook + ErrorPassthroughRule, Group, IdempotencyRecord, PaymentAuditLog, + PaymentOrder, PaymentProviderInstance, PromoCode, + PromoCodeUsage, Proxy, RedeemCode, SecuritySecret, Setting, SubscriptionPlan, + TLSFingerprintProfile, UsageCleanupTask, UsageLog, User, UserAllowedGroup, + UserAttributeDefinition, UserAttributeValue, UserSubscription []ent.Hook } inters struct { APIKey, Account, AccountGroup, Announcement, AnnouncementRead, - ErrorPassthroughRule, Group, IdempotencyRecord, PromoCode, PromoCodeUsage, - Proxy, RedeemCode, SecuritySecret, Setting, TLSFingerprintProfile, - UsageCleanupTask, UsageLog, User, UserAllowedGroup, UserAttributeDefinition, - UserAttributeValue, UserSubscription []ent.Interceptor + ErrorPassthroughRule, Group, IdempotencyRecord, PaymentAuditLog, + PaymentOrder, PaymentProviderInstance, PromoCode, + PromoCodeUsage, Proxy, RedeemCode, SecuritySecret, Setting, SubscriptionPlan, + TLSFingerprintProfile, UsageCleanupTask, UsageLog, User, UserAllowedGroup, + UserAttributeDefinition, UserAttributeValue, UserSubscription []ent.Interceptor } ) diff --git a/backend/ent/ent.go b/backend/ent/ent.go index bdeaed8a8e..96ed5e03a9 100644 --- a/backend/ent/ent.go +++ b/backend/ent/ent.go @@ -20,12 +20,16 @@ import ( "github.com/Wei-Shaw/sub2api/ent/errorpassthroughrule" "github.com/Wei-Shaw/sub2api/ent/group" "github.com/Wei-Shaw/sub2api/ent/idempotencyrecord" + "github.com/Wei-Shaw/sub2api/ent/paymentauditlog" + "github.com/Wei-Shaw/sub2api/ent/paymentorder" + "github.com/Wei-Shaw/sub2api/ent/paymentproviderinstance" "github.com/Wei-Shaw/sub2api/ent/promocode" "github.com/Wei-Shaw/sub2api/ent/promocodeusage" "github.com/Wei-Shaw/sub2api/ent/proxy" "github.com/Wei-Shaw/sub2api/ent/redeemcode" "github.com/Wei-Shaw/sub2api/ent/securitysecret" "github.com/Wei-Shaw/sub2api/ent/setting" + "github.com/Wei-Shaw/sub2api/ent/subscriptionplan" "github.com/Wei-Shaw/sub2api/ent/tlsfingerprintprofile" "github.com/Wei-Shaw/sub2api/ent/usagecleanuptask" "github.com/Wei-Shaw/sub2api/ent/usagelog" @@ -102,12 +106,16 @@ func checkColumn(t, c string) error { errorpassthroughrule.Table: errorpassthroughrule.ValidColumn, group.Table: group.ValidColumn, idempotencyrecord.Table: idempotencyrecord.ValidColumn, + paymentauditlog.Table: paymentauditlog.ValidColumn, + paymentorder.Table: paymentorder.ValidColumn, + paymentproviderinstance.Table: paymentproviderinstance.ValidColumn, promocode.Table: promocode.ValidColumn, promocodeusage.Table: promocodeusage.ValidColumn, proxy.Table: proxy.ValidColumn, redeemcode.Table: redeemcode.ValidColumn, securitysecret.Table: securitysecret.ValidColumn, setting.Table: setting.ValidColumn, + subscriptionplan.Table: subscriptionplan.ValidColumn, tlsfingerprintprofile.Table: tlsfingerprintprofile.ValidColumn, usagecleanuptask.Table: usagecleanuptask.ValidColumn, usagelog.Table: usagelog.ValidColumn, diff --git a/backend/ent/hook/hook.go b/backend/ent/hook/hook.go index f6f7b4e9b4..199dacea0e 100644 --- a/backend/ent/hook/hook.go +++ b/backend/ent/hook/hook.go @@ -105,6 +105,42 @@ func (f IdempotencyRecordFunc) Mutate(ctx context.Context, m ent.Mutation) (ent. return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.IdempotencyRecordMutation", m) } +// The PaymentAuditLogFunc type is an adapter to allow the use of ordinary +// function as PaymentAuditLog mutator. +type PaymentAuditLogFunc func(context.Context, *ent.PaymentAuditLogMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f PaymentAuditLogFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.PaymentAuditLogMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PaymentAuditLogMutation", m) +} + +// The PaymentOrderFunc type is an adapter to allow the use of ordinary +// function as PaymentOrder mutator. +type PaymentOrderFunc func(context.Context, *ent.PaymentOrderMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f PaymentOrderFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.PaymentOrderMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PaymentOrderMutation", m) +} + +// The PaymentProviderInstanceFunc type is an adapter to allow the use of ordinary +// function as PaymentProviderInstance mutator. +type PaymentProviderInstanceFunc func(context.Context, *ent.PaymentProviderInstanceMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f PaymentProviderInstanceFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.PaymentProviderInstanceMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PaymentProviderInstanceMutation", m) +} + // The PromoCodeFunc type is an adapter to allow the use of ordinary // function as PromoCode mutator. type PromoCodeFunc func(context.Context, *ent.PromoCodeMutation) (ent.Value, error) @@ -177,6 +213,18 @@ func (f SettingFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, err return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.SettingMutation", m) } +// The SubscriptionPlanFunc type is an adapter to allow the use of ordinary +// function as SubscriptionPlan mutator. +type SubscriptionPlanFunc func(context.Context, *ent.SubscriptionPlanMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f SubscriptionPlanFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.SubscriptionPlanMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.SubscriptionPlanMutation", m) +} + // The TLSFingerprintProfileFunc type is an adapter to allow the use of ordinary // function as TLSFingerprintProfile mutator. type TLSFingerprintProfileFunc func(context.Context, *ent.TLSFingerprintProfileMutation) (ent.Value, error) diff --git a/backend/ent/intercept/intercept.go b/backend/ent/intercept/intercept.go index 13169ca715..77d3e16e06 100644 --- a/backend/ent/intercept/intercept.go +++ b/backend/ent/intercept/intercept.go @@ -16,6 +16,9 @@ import ( "github.com/Wei-Shaw/sub2api/ent/errorpassthroughrule" "github.com/Wei-Shaw/sub2api/ent/group" "github.com/Wei-Shaw/sub2api/ent/idempotencyrecord" + "github.com/Wei-Shaw/sub2api/ent/paymentauditlog" + "github.com/Wei-Shaw/sub2api/ent/paymentorder" + "github.com/Wei-Shaw/sub2api/ent/paymentproviderinstance" "github.com/Wei-Shaw/sub2api/ent/predicate" "github.com/Wei-Shaw/sub2api/ent/promocode" "github.com/Wei-Shaw/sub2api/ent/promocodeusage" @@ -23,6 +26,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/redeemcode" "github.com/Wei-Shaw/sub2api/ent/securitysecret" "github.com/Wei-Shaw/sub2api/ent/setting" + "github.com/Wei-Shaw/sub2api/ent/subscriptionplan" "github.com/Wei-Shaw/sub2api/ent/tlsfingerprintprofile" "github.com/Wei-Shaw/sub2api/ent/usagecleanuptask" "github.com/Wei-Shaw/sub2api/ent/usagelog" @@ -305,6 +309,88 @@ func (f TraverseIdempotencyRecord) Traverse(ctx context.Context, q ent.Query) er return fmt.Errorf("unexpected query type %T. expect *ent.IdempotencyRecordQuery", q) } +// The PaymentAuditLogFunc type is an adapter to allow the use of ordinary function as a Querier. +type PaymentAuditLogFunc func(context.Context, *ent.PaymentAuditLogQuery) (ent.Value, error) + +// Query calls f(ctx, q). +func (f PaymentAuditLogFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) { + if q, ok := q.(*ent.PaymentAuditLogQuery); ok { + return f(ctx, q) + } + return nil, fmt.Errorf("unexpected query type %T. expect *ent.PaymentAuditLogQuery", q) +} + +// The TraversePaymentAuditLog type is an adapter to allow the use of ordinary function as Traverser. +type TraversePaymentAuditLog func(context.Context, *ent.PaymentAuditLogQuery) error + +// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline. +func (f TraversePaymentAuditLog) Intercept(next ent.Querier) ent.Querier { + return next +} + +// Traverse calls f(ctx, q). +func (f TraversePaymentAuditLog) Traverse(ctx context.Context, q ent.Query) error { + if q, ok := q.(*ent.PaymentAuditLogQuery); ok { + return f(ctx, q) + } + return fmt.Errorf("unexpected query type %T. expect *ent.PaymentAuditLogQuery", q) +} + + +// The PaymentOrderFunc type is an adapter to allow the use of ordinary function as a Querier. +type PaymentOrderFunc func(context.Context, *ent.PaymentOrderQuery) (ent.Value, error) + +// Query calls f(ctx, q). +func (f PaymentOrderFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) { + if q, ok := q.(*ent.PaymentOrderQuery); ok { + return f(ctx, q) + } + return nil, fmt.Errorf("unexpected query type %T. expect *ent.PaymentOrderQuery", q) +} + +// The TraversePaymentOrder type is an adapter to allow the use of ordinary function as Traverser. +type TraversePaymentOrder func(context.Context, *ent.PaymentOrderQuery) error + +// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline. +func (f TraversePaymentOrder) Intercept(next ent.Querier) ent.Querier { + return next +} + +// Traverse calls f(ctx, q). +func (f TraversePaymentOrder) Traverse(ctx context.Context, q ent.Query) error { + if q, ok := q.(*ent.PaymentOrderQuery); ok { + return f(ctx, q) + } + return fmt.Errorf("unexpected query type %T. expect *ent.PaymentOrderQuery", q) +} + +// The PaymentProviderInstanceFunc type is an adapter to allow the use of ordinary function as a Querier. +type PaymentProviderInstanceFunc func(context.Context, *ent.PaymentProviderInstanceQuery) (ent.Value, error) + +// Query calls f(ctx, q). +func (f PaymentProviderInstanceFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) { + if q, ok := q.(*ent.PaymentProviderInstanceQuery); ok { + return f(ctx, q) + } + return nil, fmt.Errorf("unexpected query type %T. expect *ent.PaymentProviderInstanceQuery", q) +} + +// The TraversePaymentProviderInstance type is an adapter to allow the use of ordinary function as Traverser. +type TraversePaymentProviderInstance func(context.Context, *ent.PaymentProviderInstanceQuery) error + +// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline. +func (f TraversePaymentProviderInstance) Intercept(next ent.Querier) ent.Querier { + return next +} + +// Traverse calls f(ctx, q). +func (f TraversePaymentProviderInstance) Traverse(ctx context.Context, q ent.Query) error { + if q, ok := q.(*ent.PaymentProviderInstanceQuery); ok { + return f(ctx, q) + } + return fmt.Errorf("unexpected query type %T. expect *ent.PaymentProviderInstanceQuery", q) +} + // The PromoCodeFunc type is an adapter to allow the use of ordinary function as a Querier. type PromoCodeFunc func(context.Context, *ent.PromoCodeQuery) (ent.Value, error) @@ -467,6 +553,33 @@ func (f TraverseSetting) Traverse(ctx context.Context, q ent.Query) error { return fmt.Errorf("unexpected query type %T. expect *ent.SettingQuery", q) } +// The SubscriptionPlanFunc type is an adapter to allow the use of ordinary function as a Querier. +type SubscriptionPlanFunc func(context.Context, *ent.SubscriptionPlanQuery) (ent.Value, error) + +// Query calls f(ctx, q). +func (f SubscriptionPlanFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) { + if q, ok := q.(*ent.SubscriptionPlanQuery); ok { + return f(ctx, q) + } + return nil, fmt.Errorf("unexpected query type %T. expect *ent.SubscriptionPlanQuery", q) +} + +// The TraverseSubscriptionPlan type is an adapter to allow the use of ordinary function as Traverser. +type TraverseSubscriptionPlan func(context.Context, *ent.SubscriptionPlanQuery) error + +// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline. +func (f TraverseSubscriptionPlan) Intercept(next ent.Querier) ent.Querier { + return next +} + +// Traverse calls f(ctx, q). +func (f TraverseSubscriptionPlan) Traverse(ctx context.Context, q ent.Query) error { + if q, ok := q.(*ent.SubscriptionPlanQuery); ok { + return f(ctx, q) + } + return fmt.Errorf("unexpected query type %T. expect *ent.SubscriptionPlanQuery", q) +} + // The TLSFingerprintProfileFunc type is an adapter to allow the use of ordinary function as a Querier. type TLSFingerprintProfileFunc func(context.Context, *ent.TLSFingerprintProfileQuery) (ent.Value, error) @@ -702,6 +815,12 @@ func NewQuery(q ent.Query) (Query, error) { return &query[*ent.GroupQuery, predicate.Group, group.OrderOption]{typ: ent.TypeGroup, tq: q}, nil case *ent.IdempotencyRecordQuery: return &query[*ent.IdempotencyRecordQuery, predicate.IdempotencyRecord, idempotencyrecord.OrderOption]{typ: ent.TypeIdempotencyRecord, tq: q}, nil + case *ent.PaymentAuditLogQuery: + return &query[*ent.PaymentAuditLogQuery, predicate.PaymentAuditLog, paymentauditlog.OrderOption]{typ: ent.TypePaymentAuditLog, tq: q}, nil + case *ent.PaymentOrderQuery: + return &query[*ent.PaymentOrderQuery, predicate.PaymentOrder, paymentorder.OrderOption]{typ: ent.TypePaymentOrder, tq: q}, nil + case *ent.PaymentProviderInstanceQuery: + return &query[*ent.PaymentProviderInstanceQuery, predicate.PaymentProviderInstance, paymentproviderinstance.OrderOption]{typ: ent.TypePaymentProviderInstance, tq: q}, nil case *ent.PromoCodeQuery: return &query[*ent.PromoCodeQuery, predicate.PromoCode, promocode.OrderOption]{typ: ent.TypePromoCode, tq: q}, nil case *ent.PromoCodeUsageQuery: @@ -714,6 +833,8 @@ func NewQuery(q ent.Query) (Query, error) { return &query[*ent.SecuritySecretQuery, predicate.SecuritySecret, securitysecret.OrderOption]{typ: ent.TypeSecuritySecret, tq: q}, nil case *ent.SettingQuery: return &query[*ent.SettingQuery, predicate.Setting, setting.OrderOption]{typ: ent.TypeSetting, tq: q}, nil + case *ent.SubscriptionPlanQuery: + return &query[*ent.SubscriptionPlanQuery, predicate.SubscriptionPlan, subscriptionplan.OrderOption]{typ: ent.TypeSubscriptionPlan, tq: q}, nil case *ent.TLSFingerprintProfileQuery: return &query[*ent.TLSFingerprintProfileQuery, predicate.TLSFingerprintProfile, tlsfingerprintprofile.OrderOption]{typ: ent.TypeTLSFingerprintProfile, tq: q}, nil case *ent.UsageCleanupTaskQuery: diff --git a/backend/ent/migrate/schema.go b/backend/ent/migrate/schema.go index 5400bf9319..c0f893840e 100644 --- a/backend/ent/migrate/schema.go +++ b/backend/ent/migrate/schema.go @@ -484,6 +484,151 @@ var ( }, }, } + // PaymentAuditLogsColumns holds the columns for the "payment_audit_logs" table. + PaymentAuditLogsColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt64, Increment: true}, + {Name: "order_id", Type: field.TypeString, Size: 64}, + {Name: "action", Type: field.TypeString, Size: 50}, + {Name: "detail", Type: field.TypeString, Default: "", SchemaType: map[string]string{"postgres": "text"}}, + {Name: "operator", Type: field.TypeString, Size: 100, Default: "system"}, + {Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, + } + // PaymentAuditLogsTable holds the schema information for the "payment_audit_logs" table. + PaymentAuditLogsTable = &schema.Table{ + Name: "payment_audit_logs", + Columns: PaymentAuditLogsColumns, + PrimaryKey: []*schema.Column{PaymentAuditLogsColumns[0]}, + Indexes: []*schema.Index{ + { + Name: "paymentauditlog_order_id", + Unique: false, + Columns: []*schema.Column{PaymentAuditLogsColumns[1]}, + }, + }, + } + // PaymentOrdersColumns holds the columns for the "payment_orders" table. + PaymentOrdersColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt64, Increment: true}, + {Name: "user_email", Type: field.TypeString, Size: 255}, + {Name: "user_name", Type: field.TypeString, Size: 100}, + {Name: "user_notes", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}}, + {Name: "amount", Type: field.TypeFloat64, SchemaType: map[string]string{"postgres": "decimal(20,2)"}}, + {Name: "pay_amount", Type: field.TypeFloat64, SchemaType: map[string]string{"postgres": "decimal(20,2)"}}, + {Name: "fee_rate", Type: field.TypeFloat64, Default: 0, SchemaType: map[string]string{"postgres": "decimal(10,4)"}}, + {Name: "recharge_code", Type: field.TypeString, Size: 64}, + {Name: "payment_type", Type: field.TypeString, Size: 30}, + {Name: "payment_trade_no", Type: field.TypeString, Size: 128}, + {Name: "pay_url", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}}, + {Name: "qr_code", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}}, + {Name: "qr_code_img", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}}, + {Name: "order_type", Type: field.TypeString, Size: 20, Default: "balance"}, + {Name: "plan_id", Type: field.TypeInt64, Nullable: true}, + {Name: "subscription_group_id", Type: field.TypeInt64, Nullable: true}, + {Name: "subscription_days", Type: field.TypeInt, Nullable: true}, + {Name: "provider_instance_id", Type: field.TypeString, Nullable: true, Size: 64}, + {Name: "status", Type: field.TypeString, Size: 30, Default: "PENDING"}, + {Name: "refund_amount", Type: field.TypeFloat64, Default: 0, SchemaType: map[string]string{"postgres": "decimal(20,2)"}}, + {Name: "refund_reason", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}}, + {Name: "refund_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "force_refund", Type: field.TypeBool, Default: false}, + {Name: "refund_requested_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "refund_request_reason", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}}, + {Name: "refund_requested_by", Type: field.TypeString, Nullable: true, Size: 20}, + {Name: "expires_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "paid_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "completed_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "failed_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "failed_reason", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}}, + {Name: "client_ip", Type: field.TypeString, Size: 50}, + {Name: "src_host", Type: field.TypeString, Size: 255}, + {Name: "src_url", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}}, + {Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "user_id", Type: field.TypeInt64}, + } + // PaymentOrdersTable holds the schema information for the "payment_orders" table. + PaymentOrdersTable = &schema.Table{ + Name: "payment_orders", + Columns: PaymentOrdersColumns, + PrimaryKey: []*schema.Column{PaymentOrdersColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "payment_orders_users_payment_orders", + Columns: []*schema.Column{PaymentOrdersColumns[36]}, + RefColumns: []*schema.Column{UsersColumns[0]}, + OnDelete: schema.NoAction, + }, + }, + Indexes: []*schema.Index{ + { + Name: "paymentorder_user_id", + Unique: false, + Columns: []*schema.Column{PaymentOrdersColumns[36]}, + }, + { + Name: "paymentorder_status", + Unique: false, + Columns: []*schema.Column{PaymentOrdersColumns[18]}, + }, + { + Name: "paymentorder_expires_at", + Unique: false, + Columns: []*schema.Column{PaymentOrdersColumns[26]}, + }, + { + Name: "paymentorder_created_at", + Unique: false, + Columns: []*schema.Column{PaymentOrdersColumns[34]}, + }, + { + Name: "paymentorder_paid_at", + Unique: false, + Columns: []*schema.Column{PaymentOrdersColumns[27]}, + }, + { + Name: "paymentorder_payment_type_paid_at", + Unique: false, + Columns: []*schema.Column{PaymentOrdersColumns[8], PaymentOrdersColumns[27]}, + }, + { + Name: "paymentorder_order_type", + Unique: false, + Columns: []*schema.Column{PaymentOrdersColumns[13]}, + }, + }, + } + // PaymentProviderInstancesColumns holds the columns for the "payment_provider_instances" table. + PaymentProviderInstancesColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt64, Increment: true}, + {Name: "provider_key", Type: field.TypeString, Size: 30}, + {Name: "name", Type: field.TypeString, Size: 100, Default: ""}, + {Name: "config", Type: field.TypeString, SchemaType: map[string]string{"postgres": "text"}}, + {Name: "supported_types", Type: field.TypeString, Size: 200, Default: ""}, + {Name: "enabled", Type: field.TypeBool, Default: true}, + {Name: "sort_order", Type: field.TypeInt, Default: 0}, + {Name: "limits", Type: field.TypeString, Default: "", SchemaType: map[string]string{"postgres": "text"}}, + {Name: "refund_enabled", Type: field.TypeBool, Default: false}, + {Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, + } + // PaymentProviderInstancesTable holds the schema information for the "payment_provider_instances" table. + PaymentProviderInstancesTable = &schema.Table{ + Name: "payment_provider_instances", + Columns: PaymentProviderInstancesColumns, + PrimaryKey: []*schema.Column{PaymentProviderInstancesColumns[0]}, + Indexes: []*schema.Index{ + { + Name: "paymentproviderinstance_provider_key", + Unique: false, + Columns: []*schema.Column{PaymentProviderInstancesColumns[1]}, + }, + { + Name: "paymentproviderinstance_enabled", + Unique: false, + Columns: []*schema.Column{PaymentProviderInstancesColumns[5]}, + }, + }, + } // PromoCodesColumns holds the columns for the "promo_codes" table. PromoCodesColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt64, Increment: true}, @@ -670,6 +815,41 @@ var ( Columns: SettingsColumns, PrimaryKey: []*schema.Column{SettingsColumns[0]}, } + // SubscriptionPlansColumns holds the columns for the "subscription_plans" table. + SubscriptionPlansColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt64, Increment: true}, + {Name: "group_id", Type: field.TypeInt64}, + {Name: "name", Type: field.TypeString, Size: 100}, + {Name: "description", Type: field.TypeString, Default: "", SchemaType: map[string]string{"postgres": "text"}}, + {Name: "price", Type: field.TypeFloat64, SchemaType: map[string]string{"postgres": "decimal(20,2)"}}, + {Name: "original_price", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,2)"}}, + {Name: "validity_days", Type: field.TypeInt, Default: 30}, + {Name: "validity_unit", Type: field.TypeString, Size: 10, Default: "day"}, + {Name: "features", Type: field.TypeString, Default: "", SchemaType: map[string]string{"postgres": "text"}}, + {Name: "product_name", Type: field.TypeString, Size: 100, Default: ""}, + {Name: "for_sale", Type: field.TypeBool, Default: true}, + {Name: "sort_order", Type: field.TypeInt, Default: 0}, + {Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, + } + // SubscriptionPlansTable holds the schema information for the "subscription_plans" table. + SubscriptionPlansTable = &schema.Table{ + Name: "subscription_plans", + Columns: SubscriptionPlansColumns, + PrimaryKey: []*schema.Column{SubscriptionPlansColumns[0]}, + Indexes: []*schema.Index{ + { + Name: "subscriptionplan_group_id", + Unique: false, + Columns: []*schema.Column{SubscriptionPlansColumns[1]}, + }, + { + Name: "subscriptionplan_for_sale", + Unique: false, + Columns: []*schema.Column{SubscriptionPlansColumns[10]}, + }, + }, + } // TLSFingerprintProfilesColumns holds the columns for the "tls_fingerprint_profiles" table. TLSFingerprintProfilesColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt64, Increment: true}, @@ -1127,12 +1307,16 @@ var ( ErrorPassthroughRulesTable, GroupsTable, IdempotencyRecordsTable, + PaymentAuditLogsTable, + PaymentOrdersTable, + PaymentProviderInstancesTable, PromoCodesTable, PromoCodeUsagesTable, ProxiesTable, RedeemCodesTable, SecuritySecretsTable, SettingsTable, + SubscriptionPlansTable, TLSFingerprintProfilesTable, UsageCleanupTasksTable, UsageLogsTable, @@ -1176,6 +1360,16 @@ func init() { IdempotencyRecordsTable.Annotation = &entsql.Annotation{ Table: "idempotency_records", } + PaymentAuditLogsTable.Annotation = &entsql.Annotation{ + Table: "payment_audit_logs", + } + PaymentOrdersTable.ForeignKeys[0].RefTable = UsersTable + PaymentOrdersTable.Annotation = &entsql.Annotation{ + Table: "payment_orders", + } + PaymentProviderInstancesTable.Annotation = &entsql.Annotation{ + Table: "payment_provider_instances", + } PromoCodesTable.Annotation = &entsql.Annotation{ Table: "promo_codes", } @@ -1198,6 +1392,9 @@ func init() { SettingsTable.Annotation = &entsql.Annotation{ Table: "settings", } + SubscriptionPlansTable.Annotation = &entsql.Annotation{ + Table: "subscription_plans", + } TLSFingerprintProfilesTable.Annotation = &entsql.Annotation{ Table: "tls_fingerprint_profiles", } diff --git a/backend/ent/mutation.go b/backend/ent/mutation.go index d206039af4..663a13811d 100644 --- a/backend/ent/mutation.go +++ b/backend/ent/mutation.go @@ -20,6 +20,9 @@ import ( "github.com/Wei-Shaw/sub2api/ent/errorpassthroughrule" "github.com/Wei-Shaw/sub2api/ent/group" "github.com/Wei-Shaw/sub2api/ent/idempotencyrecord" + "github.com/Wei-Shaw/sub2api/ent/paymentauditlog" + "github.com/Wei-Shaw/sub2api/ent/paymentorder" + "github.com/Wei-Shaw/sub2api/ent/paymentproviderinstance" "github.com/Wei-Shaw/sub2api/ent/predicate" "github.com/Wei-Shaw/sub2api/ent/promocode" "github.com/Wei-Shaw/sub2api/ent/promocodeusage" @@ -27,6 +30,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/redeemcode" "github.com/Wei-Shaw/sub2api/ent/securitysecret" "github.com/Wei-Shaw/sub2api/ent/setting" + "github.com/Wei-Shaw/sub2api/ent/subscriptionplan" "github.com/Wei-Shaw/sub2api/ent/tlsfingerprintprofile" "github.com/Wei-Shaw/sub2api/ent/usagecleanuptask" "github.com/Wei-Shaw/sub2api/ent/usagelog" @@ -55,12 +59,16 @@ const ( TypeErrorPassthroughRule = "ErrorPassthroughRule" TypeGroup = "Group" TypeIdempotencyRecord = "IdempotencyRecord" + TypePaymentAuditLog = "PaymentAuditLog" + TypePaymentOrder = "PaymentOrder" + TypePaymentProviderInstance = "PaymentProviderInstance" TypePromoCode = "PromoCode" TypePromoCodeUsage = "PromoCodeUsage" TypeProxy = "Proxy" TypeRedeemCode = "RedeemCode" TypeSecuritySecret = "SecuritySecret" TypeSetting = "Setting" + TypeSubscriptionPlan = "SubscriptionPlan" TypeTLSFingerprintProfile = "TLSFingerprintProfile" TypeUsageCleanupTask = "UsageCleanupTask" TypeUsageLog = "UsageLog" @@ -12129,6 +12137,4248 @@ func (m *IdempotencyRecordMutation) ResetEdge(name string) error { return fmt.Errorf("unknown IdempotencyRecord edge %s", name) } +// PaymentAuditLogMutation represents an operation that mutates the PaymentAuditLog nodes in the graph. +type PaymentAuditLogMutation struct { + config + op Op + typ string + id *int64 + order_id *string + action *string + detail *string + operator *string + created_at *time.Time + clearedFields map[string]struct{} + done bool + oldValue func(context.Context) (*PaymentAuditLog, error) + predicates []predicate.PaymentAuditLog +} + +var _ ent.Mutation = (*PaymentAuditLogMutation)(nil) + +// paymentauditlogOption allows management of the mutation configuration using functional options. +type paymentauditlogOption func(*PaymentAuditLogMutation) + +// newPaymentAuditLogMutation creates new mutation for the PaymentAuditLog entity. +func newPaymentAuditLogMutation(c config, op Op, opts ...paymentauditlogOption) *PaymentAuditLogMutation { + m := &PaymentAuditLogMutation{ + config: c, + op: op, + typ: TypePaymentAuditLog, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withPaymentAuditLogID sets the ID field of the mutation. +func withPaymentAuditLogID(id int64) paymentauditlogOption { + return func(m *PaymentAuditLogMutation) { + var ( + err error + once sync.Once + value *PaymentAuditLog + ) + m.oldValue = func(ctx context.Context) (*PaymentAuditLog, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().PaymentAuditLog.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withPaymentAuditLog sets the old PaymentAuditLog of the mutation. +func withPaymentAuditLog(node *PaymentAuditLog) paymentauditlogOption { + return func(m *PaymentAuditLogMutation) { + m.oldValue = func(context.Context) (*PaymentAuditLog, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m PaymentAuditLogMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m PaymentAuditLogMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *PaymentAuditLogMutation) ID() (id int64, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *PaymentAuditLogMutation) IDs(ctx context.Context) ([]int64, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []int64{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().PaymentAuditLog.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetOrderID sets the "order_id" field. +func (m *PaymentAuditLogMutation) SetOrderID(s string) { + m.order_id = &s +} + +// OrderID returns the value of the "order_id" field in the mutation. +func (m *PaymentAuditLogMutation) OrderID() (r string, exists bool) { + v := m.order_id + if v == nil { + return + } + return *v, true +} + +// OldOrderID returns the old "order_id" field's value of the PaymentAuditLog entity. +// If the PaymentAuditLog object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentAuditLogMutation) OldOrderID(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldOrderID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldOrderID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldOrderID: %w", err) + } + return oldValue.OrderID, nil +} + +// ResetOrderID resets all changes to the "order_id" field. +func (m *PaymentAuditLogMutation) ResetOrderID() { + m.order_id = nil +} + +// SetAction sets the "action" field. +func (m *PaymentAuditLogMutation) SetAction(s string) { + m.action = &s +} + +// Action returns the value of the "action" field in the mutation. +func (m *PaymentAuditLogMutation) Action() (r string, exists bool) { + v := m.action + if v == nil { + return + } + return *v, true +} + +// OldAction returns the old "action" field's value of the PaymentAuditLog entity. +// If the PaymentAuditLog object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentAuditLogMutation) OldAction(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldAction is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldAction requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldAction: %w", err) + } + return oldValue.Action, nil +} + +// ResetAction resets all changes to the "action" field. +func (m *PaymentAuditLogMutation) ResetAction() { + m.action = nil +} + +// SetDetail sets the "detail" field. +func (m *PaymentAuditLogMutation) SetDetail(s string) { + m.detail = &s +} + +// Detail returns the value of the "detail" field in the mutation. +func (m *PaymentAuditLogMutation) Detail() (r string, exists bool) { + v := m.detail + if v == nil { + return + } + return *v, true +} + +// OldDetail returns the old "detail" field's value of the PaymentAuditLog entity. +// If the PaymentAuditLog object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentAuditLogMutation) OldDetail(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldDetail is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldDetail requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldDetail: %w", err) + } + return oldValue.Detail, nil +} + +// ResetDetail resets all changes to the "detail" field. +func (m *PaymentAuditLogMutation) ResetDetail() { + m.detail = nil +} + +// SetOperator sets the "operator" field. +func (m *PaymentAuditLogMutation) SetOperator(s string) { + m.operator = &s +} + +// Operator returns the value of the "operator" field in the mutation. +func (m *PaymentAuditLogMutation) Operator() (r string, exists bool) { + v := m.operator + if v == nil { + return + } + return *v, true +} + +// OldOperator returns the old "operator" field's value of the PaymentAuditLog entity. +// If the PaymentAuditLog object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentAuditLogMutation) OldOperator(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldOperator is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldOperator requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldOperator: %w", err) + } + return oldValue.Operator, nil +} + +// ResetOperator resets all changes to the "operator" field. +func (m *PaymentAuditLogMutation) ResetOperator() { + m.operator = nil +} + +// SetCreatedAt sets the "created_at" field. +func (m *PaymentAuditLogMutation) SetCreatedAt(t time.Time) { + m.created_at = &t +} + +// CreatedAt returns the value of the "created_at" field in the mutation. +func (m *PaymentAuditLogMutation) CreatedAt() (r time.Time, exists bool) { + v := m.created_at + if v == nil { + return + } + return *v, true +} + +// OldCreatedAt returns the old "created_at" field's value of the PaymentAuditLog entity. +// If the PaymentAuditLog object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentAuditLogMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldCreatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err) + } + return oldValue.CreatedAt, nil +} + +// ResetCreatedAt resets all changes to the "created_at" field. +func (m *PaymentAuditLogMutation) ResetCreatedAt() { + m.created_at = nil +} + +// Where appends a list predicates to the PaymentAuditLogMutation builder. +func (m *PaymentAuditLogMutation) Where(ps ...predicate.PaymentAuditLog) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the PaymentAuditLogMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *PaymentAuditLogMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.PaymentAuditLog, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *PaymentAuditLogMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *PaymentAuditLogMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (PaymentAuditLog). +func (m *PaymentAuditLogMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *PaymentAuditLogMutation) Fields() []string { + fields := make([]string, 0, 5) + if m.order_id != nil { + fields = append(fields, paymentauditlog.FieldOrderID) + } + if m.action != nil { + fields = append(fields, paymentauditlog.FieldAction) + } + if m.detail != nil { + fields = append(fields, paymentauditlog.FieldDetail) + } + if m.operator != nil { + fields = append(fields, paymentauditlog.FieldOperator) + } + if m.created_at != nil { + fields = append(fields, paymentauditlog.FieldCreatedAt) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *PaymentAuditLogMutation) Field(name string) (ent.Value, bool) { + switch name { + case paymentauditlog.FieldOrderID: + return m.OrderID() + case paymentauditlog.FieldAction: + return m.Action() + case paymentauditlog.FieldDetail: + return m.Detail() + case paymentauditlog.FieldOperator: + return m.Operator() + case paymentauditlog.FieldCreatedAt: + return m.CreatedAt() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *PaymentAuditLogMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case paymentauditlog.FieldOrderID: + return m.OldOrderID(ctx) + case paymentauditlog.FieldAction: + return m.OldAction(ctx) + case paymentauditlog.FieldDetail: + return m.OldDetail(ctx) + case paymentauditlog.FieldOperator: + return m.OldOperator(ctx) + case paymentauditlog.FieldCreatedAt: + return m.OldCreatedAt(ctx) + } + return nil, fmt.Errorf("unknown PaymentAuditLog field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *PaymentAuditLogMutation) SetField(name string, value ent.Value) error { + switch name { + case paymentauditlog.FieldOrderID: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOrderID(v) + return nil + case paymentauditlog.FieldAction: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAction(v) + return nil + case paymentauditlog.FieldDetail: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDetail(v) + return nil + case paymentauditlog.FieldOperator: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOperator(v) + return nil + case paymentauditlog.FieldCreatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCreatedAt(v) + return nil + } + return fmt.Errorf("unknown PaymentAuditLog field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *PaymentAuditLogMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *PaymentAuditLogMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *PaymentAuditLogMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown PaymentAuditLog numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *PaymentAuditLogMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *PaymentAuditLogMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *PaymentAuditLogMutation) ClearField(name string) error { + return fmt.Errorf("unknown PaymentAuditLog nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *PaymentAuditLogMutation) ResetField(name string) error { + switch name { + case paymentauditlog.FieldOrderID: + m.ResetOrderID() + return nil + case paymentauditlog.FieldAction: + m.ResetAction() + return nil + case paymentauditlog.FieldDetail: + m.ResetDetail() + return nil + case paymentauditlog.FieldOperator: + m.ResetOperator() + return nil + case paymentauditlog.FieldCreatedAt: + m.ResetCreatedAt() + return nil + } + return fmt.Errorf("unknown PaymentAuditLog field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *PaymentAuditLogMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *PaymentAuditLogMutation) AddedIDs(name string) []ent.Value { + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *PaymentAuditLogMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *PaymentAuditLogMutation) RemovedIDs(name string) []ent.Value { + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *PaymentAuditLogMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *PaymentAuditLogMutation) EdgeCleared(name string) bool { + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *PaymentAuditLogMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown PaymentAuditLog unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *PaymentAuditLogMutation) ResetEdge(name string) error { + return fmt.Errorf("unknown PaymentAuditLog edge %s", name) +} + +// PaymentOrderMutation represents an operation that mutates the PaymentOrder nodes in the graph. +type PaymentOrderMutation struct { + config + op Op + typ string + id *int64 + user_email *string + user_name *string + user_notes *string + amount *float64 + addamount *float64 + pay_amount *float64 + addpay_amount *float64 + fee_rate *float64 + addfee_rate *float64 + recharge_code *string + payment_type *string + payment_trade_no *string + pay_url *string + qr_code *string + qr_code_img *string + order_type *string + plan_id *int64 + addplan_id *int64 + subscription_group_id *int64 + addsubscription_group_id *int64 + subscription_days *int + addsubscription_days *int + provider_instance_id *string + status *string + refund_amount *float64 + addrefund_amount *float64 + refund_reason *string + refund_at *time.Time + force_refund *bool + refund_requested_at *time.Time + refund_request_reason *string + refund_requested_by *string + expires_at *time.Time + paid_at *time.Time + completed_at *time.Time + failed_at *time.Time + failed_reason *string + client_ip *string + src_host *string + src_url *string + created_at *time.Time + updated_at *time.Time + clearedFields map[string]struct{} + user *int64 + cleareduser bool + done bool + oldValue func(context.Context) (*PaymentOrder, error) + predicates []predicate.PaymentOrder +} + +var _ ent.Mutation = (*PaymentOrderMutation)(nil) + +// paymentorderOption allows management of the mutation configuration using functional options. +type paymentorderOption func(*PaymentOrderMutation) + +// newPaymentOrderMutation creates new mutation for the PaymentOrder entity. +func newPaymentOrderMutation(c config, op Op, opts ...paymentorderOption) *PaymentOrderMutation { + m := &PaymentOrderMutation{ + config: c, + op: op, + typ: TypePaymentOrder, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withPaymentOrderID sets the ID field of the mutation. +func withPaymentOrderID(id int64) paymentorderOption { + return func(m *PaymentOrderMutation) { + var ( + err error + once sync.Once + value *PaymentOrder + ) + m.oldValue = func(ctx context.Context) (*PaymentOrder, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().PaymentOrder.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withPaymentOrder sets the old PaymentOrder of the mutation. +func withPaymentOrder(node *PaymentOrder) paymentorderOption { + return func(m *PaymentOrderMutation) { + m.oldValue = func(context.Context) (*PaymentOrder, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m PaymentOrderMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m PaymentOrderMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *PaymentOrderMutation) ID() (id int64, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *PaymentOrderMutation) IDs(ctx context.Context) ([]int64, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []int64{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().PaymentOrder.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetUserID sets the "user_id" field. +func (m *PaymentOrderMutation) SetUserID(i int64) { + m.user = &i +} + +// UserID returns the value of the "user_id" field in the mutation. +func (m *PaymentOrderMutation) UserID() (r int64, exists bool) { + v := m.user + if v == nil { + return + } + return *v, true +} + +// OldUserID returns the old "user_id" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldUserID(ctx context.Context) (v int64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUserID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUserID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUserID: %w", err) + } + return oldValue.UserID, nil +} + +// ResetUserID resets all changes to the "user_id" field. +func (m *PaymentOrderMutation) ResetUserID() { + m.user = nil +} + +// SetUserEmail sets the "user_email" field. +func (m *PaymentOrderMutation) SetUserEmail(s string) { + m.user_email = &s +} + +// UserEmail returns the value of the "user_email" field in the mutation. +func (m *PaymentOrderMutation) UserEmail() (r string, exists bool) { + v := m.user_email + if v == nil { + return + } + return *v, true +} + +// OldUserEmail returns the old "user_email" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldUserEmail(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUserEmail is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUserEmail requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUserEmail: %w", err) + } + return oldValue.UserEmail, nil +} + +// ResetUserEmail resets all changes to the "user_email" field. +func (m *PaymentOrderMutation) ResetUserEmail() { + m.user_email = nil +} + +// SetUserName sets the "user_name" field. +func (m *PaymentOrderMutation) SetUserName(s string) { + m.user_name = &s +} + +// UserName returns the value of the "user_name" field in the mutation. +func (m *PaymentOrderMutation) UserName() (r string, exists bool) { + v := m.user_name + if v == nil { + return + } + return *v, true +} + +// OldUserName returns the old "user_name" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldUserName(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUserName is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUserName requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUserName: %w", err) + } + return oldValue.UserName, nil +} + +// ResetUserName resets all changes to the "user_name" field. +func (m *PaymentOrderMutation) ResetUserName() { + m.user_name = nil +} + +// SetUserNotes sets the "user_notes" field. +func (m *PaymentOrderMutation) SetUserNotes(s string) { + m.user_notes = &s +} + +// UserNotes returns the value of the "user_notes" field in the mutation. +func (m *PaymentOrderMutation) UserNotes() (r string, exists bool) { + v := m.user_notes + if v == nil { + return + } + return *v, true +} + +// OldUserNotes returns the old "user_notes" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldUserNotes(ctx context.Context) (v *string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUserNotes is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUserNotes requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUserNotes: %w", err) + } + return oldValue.UserNotes, nil +} + +// ClearUserNotes clears the value of the "user_notes" field. +func (m *PaymentOrderMutation) ClearUserNotes() { + m.user_notes = nil + m.clearedFields[paymentorder.FieldUserNotes] = struct{}{} +} + +// UserNotesCleared returns if the "user_notes" field was cleared in this mutation. +func (m *PaymentOrderMutation) UserNotesCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldUserNotes] + return ok +} + +// ResetUserNotes resets all changes to the "user_notes" field. +func (m *PaymentOrderMutation) ResetUserNotes() { + m.user_notes = nil + delete(m.clearedFields, paymentorder.FieldUserNotes) +} + +// SetAmount sets the "amount" field. +func (m *PaymentOrderMutation) SetAmount(f float64) { + m.amount = &f + m.addamount = nil +} + +// Amount returns the value of the "amount" field in the mutation. +func (m *PaymentOrderMutation) Amount() (r float64, exists bool) { + v := m.amount + if v == nil { + return + } + return *v, true +} + +// OldAmount returns the old "amount" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldAmount(ctx context.Context) (v float64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldAmount is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldAmount requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldAmount: %w", err) + } + return oldValue.Amount, nil +} + +// AddAmount adds f to the "amount" field. +func (m *PaymentOrderMutation) AddAmount(f float64) { + if m.addamount != nil { + *m.addamount += f + } else { + m.addamount = &f + } +} + +// AddedAmount returns the value that was added to the "amount" field in this mutation. +func (m *PaymentOrderMutation) AddedAmount() (r float64, exists bool) { + v := m.addamount + if v == nil { + return + } + return *v, true +} + +// ResetAmount resets all changes to the "amount" field. +func (m *PaymentOrderMutation) ResetAmount() { + m.amount = nil + m.addamount = nil +} + +// SetPayAmount sets the "pay_amount" field. +func (m *PaymentOrderMutation) SetPayAmount(f float64) { + m.pay_amount = &f + m.addpay_amount = nil +} + +// PayAmount returns the value of the "pay_amount" field in the mutation. +func (m *PaymentOrderMutation) PayAmount() (r float64, exists bool) { + v := m.pay_amount + if v == nil { + return + } + return *v, true +} + +// OldPayAmount returns the old "pay_amount" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldPayAmount(ctx context.Context) (v float64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldPayAmount is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldPayAmount requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldPayAmount: %w", err) + } + return oldValue.PayAmount, nil +} + +// AddPayAmount adds f to the "pay_amount" field. +func (m *PaymentOrderMutation) AddPayAmount(f float64) { + if m.addpay_amount != nil { + *m.addpay_amount += f + } else { + m.addpay_amount = &f + } +} + +// AddedPayAmount returns the value that was added to the "pay_amount" field in this mutation. +func (m *PaymentOrderMutation) AddedPayAmount() (r float64, exists bool) { + v := m.addpay_amount + if v == nil { + return + } + return *v, true +} + +// ResetPayAmount resets all changes to the "pay_amount" field. +func (m *PaymentOrderMutation) ResetPayAmount() { + m.pay_amount = nil + m.addpay_amount = nil +} + +// SetFeeRate sets the "fee_rate" field. +func (m *PaymentOrderMutation) SetFeeRate(f float64) { + m.fee_rate = &f + m.addfee_rate = nil +} + +// FeeRate returns the value of the "fee_rate" field in the mutation. +func (m *PaymentOrderMutation) FeeRate() (r float64, exists bool) { + v := m.fee_rate + if v == nil { + return + } + return *v, true +} + +// OldFeeRate returns the old "fee_rate" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldFeeRate(ctx context.Context) (v float64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldFeeRate is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldFeeRate requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldFeeRate: %w", err) + } + return oldValue.FeeRate, nil +} + +// AddFeeRate adds f to the "fee_rate" field. +func (m *PaymentOrderMutation) AddFeeRate(f float64) { + if m.addfee_rate != nil { + *m.addfee_rate += f + } else { + m.addfee_rate = &f + } +} + +// AddedFeeRate returns the value that was added to the "fee_rate" field in this mutation. +func (m *PaymentOrderMutation) AddedFeeRate() (r float64, exists bool) { + v := m.addfee_rate + if v == nil { + return + } + return *v, true +} + +// ResetFeeRate resets all changes to the "fee_rate" field. +func (m *PaymentOrderMutation) ResetFeeRate() { + m.fee_rate = nil + m.addfee_rate = nil +} + +// SetRechargeCode sets the "recharge_code" field. +func (m *PaymentOrderMutation) SetRechargeCode(s string) { + m.recharge_code = &s +} + +// RechargeCode returns the value of the "recharge_code" field in the mutation. +func (m *PaymentOrderMutation) RechargeCode() (r string, exists bool) { + v := m.recharge_code + if v == nil { + return + } + return *v, true +} + +// OldRechargeCode returns the old "recharge_code" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldRechargeCode(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRechargeCode is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRechargeCode requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRechargeCode: %w", err) + } + return oldValue.RechargeCode, nil +} + +// ResetRechargeCode resets all changes to the "recharge_code" field. +func (m *PaymentOrderMutation) ResetRechargeCode() { + m.recharge_code = nil +} + +// SetPaymentType sets the "payment_type" field. +func (m *PaymentOrderMutation) SetPaymentType(s string) { + m.payment_type = &s +} + +// PaymentType returns the value of the "payment_type" field in the mutation. +func (m *PaymentOrderMutation) PaymentType() (r string, exists bool) { + v := m.payment_type + if v == nil { + return + } + return *v, true +} + +// OldPaymentType returns the old "payment_type" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldPaymentType(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldPaymentType is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldPaymentType requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldPaymentType: %w", err) + } + return oldValue.PaymentType, nil +} + +// ResetPaymentType resets all changes to the "payment_type" field. +func (m *PaymentOrderMutation) ResetPaymentType() { + m.payment_type = nil +} + +// SetPaymentTradeNo sets the "payment_trade_no" field. +func (m *PaymentOrderMutation) SetPaymentTradeNo(s string) { + m.payment_trade_no = &s +} + +// PaymentTradeNo returns the value of the "payment_trade_no" field in the mutation. +func (m *PaymentOrderMutation) PaymentTradeNo() (r string, exists bool) { + v := m.payment_trade_no + if v == nil { + return + } + return *v, true +} + +// OldPaymentTradeNo returns the old "payment_trade_no" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldPaymentTradeNo(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldPaymentTradeNo is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldPaymentTradeNo requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldPaymentTradeNo: %w", err) + } + return oldValue.PaymentTradeNo, nil +} + +// ResetPaymentTradeNo resets all changes to the "payment_trade_no" field. +func (m *PaymentOrderMutation) ResetPaymentTradeNo() { + m.payment_trade_no = nil +} + +// SetPayURL sets the "pay_url" field. +func (m *PaymentOrderMutation) SetPayURL(s string) { + m.pay_url = &s +} + +// PayURL returns the value of the "pay_url" field in the mutation. +func (m *PaymentOrderMutation) PayURL() (r string, exists bool) { + v := m.pay_url + if v == nil { + return + } + return *v, true +} + +// OldPayURL returns the old "pay_url" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldPayURL(ctx context.Context) (v *string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldPayURL is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldPayURL requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldPayURL: %w", err) + } + return oldValue.PayURL, nil +} + +// ClearPayURL clears the value of the "pay_url" field. +func (m *PaymentOrderMutation) ClearPayURL() { + m.pay_url = nil + m.clearedFields[paymentorder.FieldPayURL] = struct{}{} +} + +// PayURLCleared returns if the "pay_url" field was cleared in this mutation. +func (m *PaymentOrderMutation) PayURLCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldPayURL] + return ok +} + +// ResetPayURL resets all changes to the "pay_url" field. +func (m *PaymentOrderMutation) ResetPayURL() { + m.pay_url = nil + delete(m.clearedFields, paymentorder.FieldPayURL) +} + +// SetQrCode sets the "qr_code" field. +func (m *PaymentOrderMutation) SetQrCode(s string) { + m.qr_code = &s +} + +// QrCode returns the value of the "qr_code" field in the mutation. +func (m *PaymentOrderMutation) QrCode() (r string, exists bool) { + v := m.qr_code + if v == nil { + return + } + return *v, true +} + +// OldQrCode returns the old "qr_code" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldQrCode(ctx context.Context) (v *string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldQrCode is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldQrCode requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldQrCode: %w", err) + } + return oldValue.QrCode, nil +} + +// ClearQrCode clears the value of the "qr_code" field. +func (m *PaymentOrderMutation) ClearQrCode() { + m.qr_code = nil + m.clearedFields[paymentorder.FieldQrCode] = struct{}{} +} + +// QrCodeCleared returns if the "qr_code" field was cleared in this mutation. +func (m *PaymentOrderMutation) QrCodeCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldQrCode] + return ok +} + +// ResetQrCode resets all changes to the "qr_code" field. +func (m *PaymentOrderMutation) ResetQrCode() { + m.qr_code = nil + delete(m.clearedFields, paymentorder.FieldQrCode) +} + +// SetQrCodeImg sets the "qr_code_img" field. +func (m *PaymentOrderMutation) SetQrCodeImg(s string) { + m.qr_code_img = &s +} + +// QrCodeImg returns the value of the "qr_code_img" field in the mutation. +func (m *PaymentOrderMutation) QrCodeImg() (r string, exists bool) { + v := m.qr_code_img + if v == nil { + return + } + return *v, true +} + +// OldQrCodeImg returns the old "qr_code_img" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldQrCodeImg(ctx context.Context) (v *string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldQrCodeImg is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldQrCodeImg requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldQrCodeImg: %w", err) + } + return oldValue.QrCodeImg, nil +} + +// ClearQrCodeImg clears the value of the "qr_code_img" field. +func (m *PaymentOrderMutation) ClearQrCodeImg() { + m.qr_code_img = nil + m.clearedFields[paymentorder.FieldQrCodeImg] = struct{}{} +} + +// QrCodeImgCleared returns if the "qr_code_img" field was cleared in this mutation. +func (m *PaymentOrderMutation) QrCodeImgCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldQrCodeImg] + return ok +} + +// ResetQrCodeImg resets all changes to the "qr_code_img" field. +func (m *PaymentOrderMutation) ResetQrCodeImg() { + m.qr_code_img = nil + delete(m.clearedFields, paymentorder.FieldQrCodeImg) +} + +// SetOrderType sets the "order_type" field. +func (m *PaymentOrderMutation) SetOrderType(s string) { + m.order_type = &s +} + +// OrderType returns the value of the "order_type" field in the mutation. +func (m *PaymentOrderMutation) OrderType() (r string, exists bool) { + v := m.order_type + if v == nil { + return + } + return *v, true +} + +// OldOrderType returns the old "order_type" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldOrderType(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldOrderType is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldOrderType requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldOrderType: %w", err) + } + return oldValue.OrderType, nil +} + +// ResetOrderType resets all changes to the "order_type" field. +func (m *PaymentOrderMutation) ResetOrderType() { + m.order_type = nil +} + +// SetPlanID sets the "plan_id" field. +func (m *PaymentOrderMutation) SetPlanID(i int64) { + m.plan_id = &i + m.addplan_id = nil +} + +// PlanID returns the value of the "plan_id" field in the mutation. +func (m *PaymentOrderMutation) PlanID() (r int64, exists bool) { + v := m.plan_id + if v == nil { + return + } + return *v, true +} + +// OldPlanID returns the old "plan_id" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldPlanID(ctx context.Context) (v *int64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldPlanID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldPlanID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldPlanID: %w", err) + } + return oldValue.PlanID, nil +} + +// AddPlanID adds i to the "plan_id" field. +func (m *PaymentOrderMutation) AddPlanID(i int64) { + if m.addplan_id != nil { + *m.addplan_id += i + } else { + m.addplan_id = &i + } +} + +// AddedPlanID returns the value that was added to the "plan_id" field in this mutation. +func (m *PaymentOrderMutation) AddedPlanID() (r int64, exists bool) { + v := m.addplan_id + if v == nil { + return + } + return *v, true +} + +// ClearPlanID clears the value of the "plan_id" field. +func (m *PaymentOrderMutation) ClearPlanID() { + m.plan_id = nil + m.addplan_id = nil + m.clearedFields[paymentorder.FieldPlanID] = struct{}{} +} + +// PlanIDCleared returns if the "plan_id" field was cleared in this mutation. +func (m *PaymentOrderMutation) PlanIDCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldPlanID] + return ok +} + +// ResetPlanID resets all changes to the "plan_id" field. +func (m *PaymentOrderMutation) ResetPlanID() { + m.plan_id = nil + m.addplan_id = nil + delete(m.clearedFields, paymentorder.FieldPlanID) +} + +// SetSubscriptionGroupID sets the "subscription_group_id" field. +func (m *PaymentOrderMutation) SetSubscriptionGroupID(i int64) { + m.subscription_group_id = &i + m.addsubscription_group_id = nil +} + +// SubscriptionGroupID returns the value of the "subscription_group_id" field in the mutation. +func (m *PaymentOrderMutation) SubscriptionGroupID() (r int64, exists bool) { + v := m.subscription_group_id + if v == nil { + return + } + return *v, true +} + +// OldSubscriptionGroupID returns the old "subscription_group_id" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldSubscriptionGroupID(ctx context.Context) (v *int64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldSubscriptionGroupID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldSubscriptionGroupID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldSubscriptionGroupID: %w", err) + } + return oldValue.SubscriptionGroupID, nil +} + +// AddSubscriptionGroupID adds i to the "subscription_group_id" field. +func (m *PaymentOrderMutation) AddSubscriptionGroupID(i int64) { + if m.addsubscription_group_id != nil { + *m.addsubscription_group_id += i + } else { + m.addsubscription_group_id = &i + } +} + +// AddedSubscriptionGroupID returns the value that was added to the "subscription_group_id" field in this mutation. +func (m *PaymentOrderMutation) AddedSubscriptionGroupID() (r int64, exists bool) { + v := m.addsubscription_group_id + if v == nil { + return + } + return *v, true +} + +// ClearSubscriptionGroupID clears the value of the "subscription_group_id" field. +func (m *PaymentOrderMutation) ClearSubscriptionGroupID() { + m.subscription_group_id = nil + m.addsubscription_group_id = nil + m.clearedFields[paymentorder.FieldSubscriptionGroupID] = struct{}{} +} + +// SubscriptionGroupIDCleared returns if the "subscription_group_id" field was cleared in this mutation. +func (m *PaymentOrderMutation) SubscriptionGroupIDCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldSubscriptionGroupID] + return ok +} + +// ResetSubscriptionGroupID resets all changes to the "subscription_group_id" field. +func (m *PaymentOrderMutation) ResetSubscriptionGroupID() { + m.subscription_group_id = nil + m.addsubscription_group_id = nil + delete(m.clearedFields, paymentorder.FieldSubscriptionGroupID) +} + +// SetSubscriptionDays sets the "subscription_days" field. +func (m *PaymentOrderMutation) SetSubscriptionDays(i int) { + m.subscription_days = &i + m.addsubscription_days = nil +} + +// SubscriptionDays returns the value of the "subscription_days" field in the mutation. +func (m *PaymentOrderMutation) SubscriptionDays() (r int, exists bool) { + v := m.subscription_days + if v == nil { + return + } + return *v, true +} + +// OldSubscriptionDays returns the old "subscription_days" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldSubscriptionDays(ctx context.Context) (v *int, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldSubscriptionDays is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldSubscriptionDays requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldSubscriptionDays: %w", err) + } + return oldValue.SubscriptionDays, nil +} + +// AddSubscriptionDays adds i to the "subscription_days" field. +func (m *PaymentOrderMutation) AddSubscriptionDays(i int) { + if m.addsubscription_days != nil { + *m.addsubscription_days += i + } else { + m.addsubscription_days = &i + } +} + +// AddedSubscriptionDays returns the value that was added to the "subscription_days" field in this mutation. +func (m *PaymentOrderMutation) AddedSubscriptionDays() (r int, exists bool) { + v := m.addsubscription_days + if v == nil { + return + } + return *v, true +} + +// ClearSubscriptionDays clears the value of the "subscription_days" field. +func (m *PaymentOrderMutation) ClearSubscriptionDays() { + m.subscription_days = nil + m.addsubscription_days = nil + m.clearedFields[paymentorder.FieldSubscriptionDays] = struct{}{} +} + +// SubscriptionDaysCleared returns if the "subscription_days" field was cleared in this mutation. +func (m *PaymentOrderMutation) SubscriptionDaysCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldSubscriptionDays] + return ok +} + +// ResetSubscriptionDays resets all changes to the "subscription_days" field. +func (m *PaymentOrderMutation) ResetSubscriptionDays() { + m.subscription_days = nil + m.addsubscription_days = nil + delete(m.clearedFields, paymentorder.FieldSubscriptionDays) +} + +// SetProviderInstanceID sets the "provider_instance_id" field. +func (m *PaymentOrderMutation) SetProviderInstanceID(s string) { + m.provider_instance_id = &s +} + +// ProviderInstanceID returns the value of the "provider_instance_id" field in the mutation. +func (m *PaymentOrderMutation) ProviderInstanceID() (r string, exists bool) { + v := m.provider_instance_id + if v == nil { + return + } + return *v, true +} + +// OldProviderInstanceID returns the old "provider_instance_id" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldProviderInstanceID(ctx context.Context) (v *string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldProviderInstanceID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldProviderInstanceID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldProviderInstanceID: %w", err) + } + return oldValue.ProviderInstanceID, nil +} + +// ClearProviderInstanceID clears the value of the "provider_instance_id" field. +func (m *PaymentOrderMutation) ClearProviderInstanceID() { + m.provider_instance_id = nil + m.clearedFields[paymentorder.FieldProviderInstanceID] = struct{}{} +} + +// ProviderInstanceIDCleared returns if the "provider_instance_id" field was cleared in this mutation. +func (m *PaymentOrderMutation) ProviderInstanceIDCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldProviderInstanceID] + return ok +} + +// ResetProviderInstanceID resets all changes to the "provider_instance_id" field. +func (m *PaymentOrderMutation) ResetProviderInstanceID() { + m.provider_instance_id = nil + delete(m.clearedFields, paymentorder.FieldProviderInstanceID) +} + +// SetStatus sets the "status" field. +func (m *PaymentOrderMutation) SetStatus(s string) { + m.status = &s +} + +// Status returns the value of the "status" field in the mutation. +func (m *PaymentOrderMutation) Status() (r string, exists bool) { + v := m.status + if v == nil { + return + } + return *v, true +} + +// OldStatus returns the old "status" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldStatus(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldStatus is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldStatus requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldStatus: %w", err) + } + return oldValue.Status, nil +} + +// ResetStatus resets all changes to the "status" field. +func (m *PaymentOrderMutation) ResetStatus() { + m.status = nil +} + +// SetRefundAmount sets the "refund_amount" field. +func (m *PaymentOrderMutation) SetRefundAmount(f float64) { + m.refund_amount = &f + m.addrefund_amount = nil +} + +// RefundAmount returns the value of the "refund_amount" field in the mutation. +func (m *PaymentOrderMutation) RefundAmount() (r float64, exists bool) { + v := m.refund_amount + if v == nil { + return + } + return *v, true +} + +// OldRefundAmount returns the old "refund_amount" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldRefundAmount(ctx context.Context) (v float64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRefundAmount is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRefundAmount requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRefundAmount: %w", err) + } + return oldValue.RefundAmount, nil +} + +// AddRefundAmount adds f to the "refund_amount" field. +func (m *PaymentOrderMutation) AddRefundAmount(f float64) { + if m.addrefund_amount != nil { + *m.addrefund_amount += f + } else { + m.addrefund_amount = &f + } +} + +// AddedRefundAmount returns the value that was added to the "refund_amount" field in this mutation. +func (m *PaymentOrderMutation) AddedRefundAmount() (r float64, exists bool) { + v := m.addrefund_amount + if v == nil { + return + } + return *v, true +} + +// ResetRefundAmount resets all changes to the "refund_amount" field. +func (m *PaymentOrderMutation) ResetRefundAmount() { + m.refund_amount = nil + m.addrefund_amount = nil +} + +// SetRefundReason sets the "refund_reason" field. +func (m *PaymentOrderMutation) SetRefundReason(s string) { + m.refund_reason = &s +} + +// RefundReason returns the value of the "refund_reason" field in the mutation. +func (m *PaymentOrderMutation) RefundReason() (r string, exists bool) { + v := m.refund_reason + if v == nil { + return + } + return *v, true +} + +// OldRefundReason returns the old "refund_reason" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldRefundReason(ctx context.Context) (v *string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRefundReason is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRefundReason requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRefundReason: %w", err) + } + return oldValue.RefundReason, nil +} + +// ClearRefundReason clears the value of the "refund_reason" field. +func (m *PaymentOrderMutation) ClearRefundReason() { + m.refund_reason = nil + m.clearedFields[paymentorder.FieldRefundReason] = struct{}{} +} + +// RefundReasonCleared returns if the "refund_reason" field was cleared in this mutation. +func (m *PaymentOrderMutation) RefundReasonCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldRefundReason] + return ok +} + +// ResetRefundReason resets all changes to the "refund_reason" field. +func (m *PaymentOrderMutation) ResetRefundReason() { + m.refund_reason = nil + delete(m.clearedFields, paymentorder.FieldRefundReason) +} + +// SetRefundAt sets the "refund_at" field. +func (m *PaymentOrderMutation) SetRefundAt(t time.Time) { + m.refund_at = &t +} + +// RefundAt returns the value of the "refund_at" field in the mutation. +func (m *PaymentOrderMutation) RefundAt() (r time.Time, exists bool) { + v := m.refund_at + if v == nil { + return + } + return *v, true +} + +// OldRefundAt returns the old "refund_at" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldRefundAt(ctx context.Context) (v *time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRefundAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRefundAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRefundAt: %w", err) + } + return oldValue.RefundAt, nil +} + +// ClearRefundAt clears the value of the "refund_at" field. +func (m *PaymentOrderMutation) ClearRefundAt() { + m.refund_at = nil + m.clearedFields[paymentorder.FieldRefundAt] = struct{}{} +} + +// RefundAtCleared returns if the "refund_at" field was cleared in this mutation. +func (m *PaymentOrderMutation) RefundAtCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldRefundAt] + return ok +} + +// ResetRefundAt resets all changes to the "refund_at" field. +func (m *PaymentOrderMutation) ResetRefundAt() { + m.refund_at = nil + delete(m.clearedFields, paymentorder.FieldRefundAt) +} + +// SetForceRefund sets the "force_refund" field. +func (m *PaymentOrderMutation) SetForceRefund(b bool) { + m.force_refund = &b +} + +// ForceRefund returns the value of the "force_refund" field in the mutation. +func (m *PaymentOrderMutation) ForceRefund() (r bool, exists bool) { + v := m.force_refund + if v == nil { + return + } + return *v, true +} + +// OldForceRefund returns the old "force_refund" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldForceRefund(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldForceRefund is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldForceRefund requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldForceRefund: %w", err) + } + return oldValue.ForceRefund, nil +} + +// ResetForceRefund resets all changes to the "force_refund" field. +func (m *PaymentOrderMutation) ResetForceRefund() { + m.force_refund = nil +} + +// SetRefundRequestedAt sets the "refund_requested_at" field. +func (m *PaymentOrderMutation) SetRefundRequestedAt(t time.Time) { + m.refund_requested_at = &t +} + +// RefundRequestedAt returns the value of the "refund_requested_at" field in the mutation. +func (m *PaymentOrderMutation) RefundRequestedAt() (r time.Time, exists bool) { + v := m.refund_requested_at + if v == nil { + return + } + return *v, true +} + +// OldRefundRequestedAt returns the old "refund_requested_at" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldRefundRequestedAt(ctx context.Context) (v *time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRefundRequestedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRefundRequestedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRefundRequestedAt: %w", err) + } + return oldValue.RefundRequestedAt, nil +} + +// ClearRefundRequestedAt clears the value of the "refund_requested_at" field. +func (m *PaymentOrderMutation) ClearRefundRequestedAt() { + m.refund_requested_at = nil + m.clearedFields[paymentorder.FieldRefundRequestedAt] = struct{}{} +} + +// RefundRequestedAtCleared returns if the "refund_requested_at" field was cleared in this mutation. +func (m *PaymentOrderMutation) RefundRequestedAtCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldRefundRequestedAt] + return ok +} + +// ResetRefundRequestedAt resets all changes to the "refund_requested_at" field. +func (m *PaymentOrderMutation) ResetRefundRequestedAt() { + m.refund_requested_at = nil + delete(m.clearedFields, paymentorder.FieldRefundRequestedAt) +} + +// SetRefundRequestReason sets the "refund_request_reason" field. +func (m *PaymentOrderMutation) SetRefundRequestReason(s string) { + m.refund_request_reason = &s +} + +// RefundRequestReason returns the value of the "refund_request_reason" field in the mutation. +func (m *PaymentOrderMutation) RefundRequestReason() (r string, exists bool) { + v := m.refund_request_reason + if v == nil { + return + } + return *v, true +} + +// OldRefundRequestReason returns the old "refund_request_reason" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldRefundRequestReason(ctx context.Context) (v *string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRefundRequestReason is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRefundRequestReason requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRefundRequestReason: %w", err) + } + return oldValue.RefundRequestReason, nil +} + +// ClearRefundRequestReason clears the value of the "refund_request_reason" field. +func (m *PaymentOrderMutation) ClearRefundRequestReason() { + m.refund_request_reason = nil + m.clearedFields[paymentorder.FieldRefundRequestReason] = struct{}{} +} + +// RefundRequestReasonCleared returns if the "refund_request_reason" field was cleared in this mutation. +func (m *PaymentOrderMutation) RefundRequestReasonCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldRefundRequestReason] + return ok +} + +// ResetRefundRequestReason resets all changes to the "refund_request_reason" field. +func (m *PaymentOrderMutation) ResetRefundRequestReason() { + m.refund_request_reason = nil + delete(m.clearedFields, paymentorder.FieldRefundRequestReason) +} + +// SetRefundRequestedBy sets the "refund_requested_by" field. +func (m *PaymentOrderMutation) SetRefundRequestedBy(s string) { + m.refund_requested_by = &s +} + +// RefundRequestedBy returns the value of the "refund_requested_by" field in the mutation. +func (m *PaymentOrderMutation) RefundRequestedBy() (r string, exists bool) { + v := m.refund_requested_by + if v == nil { + return + } + return *v, true +} + +// OldRefundRequestedBy returns the old "refund_requested_by" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldRefundRequestedBy(ctx context.Context) (v *string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRefundRequestedBy is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRefundRequestedBy requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRefundRequestedBy: %w", err) + } + return oldValue.RefundRequestedBy, nil +} + +// ClearRefundRequestedBy clears the value of the "refund_requested_by" field. +func (m *PaymentOrderMutation) ClearRefundRequestedBy() { + m.refund_requested_by = nil + m.clearedFields[paymentorder.FieldRefundRequestedBy] = struct{}{} +} + +// RefundRequestedByCleared returns if the "refund_requested_by" field was cleared in this mutation. +func (m *PaymentOrderMutation) RefundRequestedByCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldRefundRequestedBy] + return ok +} + +// ResetRefundRequestedBy resets all changes to the "refund_requested_by" field. +func (m *PaymentOrderMutation) ResetRefundRequestedBy() { + m.refund_requested_by = nil + delete(m.clearedFields, paymentorder.FieldRefundRequestedBy) +} + +// SetExpiresAt sets the "expires_at" field. +func (m *PaymentOrderMutation) SetExpiresAt(t time.Time) { + m.expires_at = &t +} + +// ExpiresAt returns the value of the "expires_at" field in the mutation. +func (m *PaymentOrderMutation) ExpiresAt() (r time.Time, exists bool) { + v := m.expires_at + if v == nil { + return + } + return *v, true +} + +// OldExpiresAt returns the old "expires_at" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldExpiresAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldExpiresAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldExpiresAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldExpiresAt: %w", err) + } + return oldValue.ExpiresAt, nil +} + +// ResetExpiresAt resets all changes to the "expires_at" field. +func (m *PaymentOrderMutation) ResetExpiresAt() { + m.expires_at = nil +} + +// SetPaidAt sets the "paid_at" field. +func (m *PaymentOrderMutation) SetPaidAt(t time.Time) { + m.paid_at = &t +} + +// PaidAt returns the value of the "paid_at" field in the mutation. +func (m *PaymentOrderMutation) PaidAt() (r time.Time, exists bool) { + v := m.paid_at + if v == nil { + return + } + return *v, true +} + +// OldPaidAt returns the old "paid_at" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldPaidAt(ctx context.Context) (v *time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldPaidAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldPaidAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldPaidAt: %w", err) + } + return oldValue.PaidAt, nil +} + +// ClearPaidAt clears the value of the "paid_at" field. +func (m *PaymentOrderMutation) ClearPaidAt() { + m.paid_at = nil + m.clearedFields[paymentorder.FieldPaidAt] = struct{}{} +} + +// PaidAtCleared returns if the "paid_at" field was cleared in this mutation. +func (m *PaymentOrderMutation) PaidAtCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldPaidAt] + return ok +} + +// ResetPaidAt resets all changes to the "paid_at" field. +func (m *PaymentOrderMutation) ResetPaidAt() { + m.paid_at = nil + delete(m.clearedFields, paymentorder.FieldPaidAt) +} + +// SetCompletedAt sets the "completed_at" field. +func (m *PaymentOrderMutation) SetCompletedAt(t time.Time) { + m.completed_at = &t +} + +// CompletedAt returns the value of the "completed_at" field in the mutation. +func (m *PaymentOrderMutation) CompletedAt() (r time.Time, exists bool) { + v := m.completed_at + if v == nil { + return + } + return *v, true +} + +// OldCompletedAt returns the old "completed_at" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldCompletedAt(ctx context.Context) (v *time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldCompletedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldCompletedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldCompletedAt: %w", err) + } + return oldValue.CompletedAt, nil +} + +// ClearCompletedAt clears the value of the "completed_at" field. +func (m *PaymentOrderMutation) ClearCompletedAt() { + m.completed_at = nil + m.clearedFields[paymentorder.FieldCompletedAt] = struct{}{} +} + +// CompletedAtCleared returns if the "completed_at" field was cleared in this mutation. +func (m *PaymentOrderMutation) CompletedAtCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldCompletedAt] + return ok +} + +// ResetCompletedAt resets all changes to the "completed_at" field. +func (m *PaymentOrderMutation) ResetCompletedAt() { + m.completed_at = nil + delete(m.clearedFields, paymentorder.FieldCompletedAt) +} + +// SetFailedAt sets the "failed_at" field. +func (m *PaymentOrderMutation) SetFailedAt(t time.Time) { + m.failed_at = &t +} + +// FailedAt returns the value of the "failed_at" field in the mutation. +func (m *PaymentOrderMutation) FailedAt() (r time.Time, exists bool) { + v := m.failed_at + if v == nil { + return + } + return *v, true +} + +// OldFailedAt returns the old "failed_at" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldFailedAt(ctx context.Context) (v *time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldFailedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldFailedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldFailedAt: %w", err) + } + return oldValue.FailedAt, nil +} + +// ClearFailedAt clears the value of the "failed_at" field. +func (m *PaymentOrderMutation) ClearFailedAt() { + m.failed_at = nil + m.clearedFields[paymentorder.FieldFailedAt] = struct{}{} +} + +// FailedAtCleared returns if the "failed_at" field was cleared in this mutation. +func (m *PaymentOrderMutation) FailedAtCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldFailedAt] + return ok +} + +// ResetFailedAt resets all changes to the "failed_at" field. +func (m *PaymentOrderMutation) ResetFailedAt() { + m.failed_at = nil + delete(m.clearedFields, paymentorder.FieldFailedAt) +} + +// SetFailedReason sets the "failed_reason" field. +func (m *PaymentOrderMutation) SetFailedReason(s string) { + m.failed_reason = &s +} + +// FailedReason returns the value of the "failed_reason" field in the mutation. +func (m *PaymentOrderMutation) FailedReason() (r string, exists bool) { + v := m.failed_reason + if v == nil { + return + } + return *v, true +} + +// OldFailedReason returns the old "failed_reason" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldFailedReason(ctx context.Context) (v *string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldFailedReason is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldFailedReason requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldFailedReason: %w", err) + } + return oldValue.FailedReason, nil +} + +// ClearFailedReason clears the value of the "failed_reason" field. +func (m *PaymentOrderMutation) ClearFailedReason() { + m.failed_reason = nil + m.clearedFields[paymentorder.FieldFailedReason] = struct{}{} +} + +// FailedReasonCleared returns if the "failed_reason" field was cleared in this mutation. +func (m *PaymentOrderMutation) FailedReasonCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldFailedReason] + return ok +} + +// ResetFailedReason resets all changes to the "failed_reason" field. +func (m *PaymentOrderMutation) ResetFailedReason() { + m.failed_reason = nil + delete(m.clearedFields, paymentorder.FieldFailedReason) +} + +// SetClientIP sets the "client_ip" field. +func (m *PaymentOrderMutation) SetClientIP(s string) { + m.client_ip = &s +} + +// ClientIP returns the value of the "client_ip" field in the mutation. +func (m *PaymentOrderMutation) ClientIP() (r string, exists bool) { + v := m.client_ip + if v == nil { + return + } + return *v, true +} + +// OldClientIP returns the old "client_ip" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldClientIP(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldClientIP is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldClientIP requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldClientIP: %w", err) + } + return oldValue.ClientIP, nil +} + +// ResetClientIP resets all changes to the "client_ip" field. +func (m *PaymentOrderMutation) ResetClientIP() { + m.client_ip = nil +} + +// SetSrcHost sets the "src_host" field. +func (m *PaymentOrderMutation) SetSrcHost(s string) { + m.src_host = &s +} + +// SrcHost returns the value of the "src_host" field in the mutation. +func (m *PaymentOrderMutation) SrcHost() (r string, exists bool) { + v := m.src_host + if v == nil { + return + } + return *v, true +} + +// OldSrcHost returns the old "src_host" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldSrcHost(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldSrcHost is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldSrcHost requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldSrcHost: %w", err) + } + return oldValue.SrcHost, nil +} + +// ResetSrcHost resets all changes to the "src_host" field. +func (m *PaymentOrderMutation) ResetSrcHost() { + m.src_host = nil +} + +// SetSrcURL sets the "src_url" field. +func (m *PaymentOrderMutation) SetSrcURL(s string) { + m.src_url = &s +} + +// SrcURL returns the value of the "src_url" field in the mutation. +func (m *PaymentOrderMutation) SrcURL() (r string, exists bool) { + v := m.src_url + if v == nil { + return + } + return *v, true +} + +// OldSrcURL returns the old "src_url" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldSrcURL(ctx context.Context) (v *string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldSrcURL is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldSrcURL requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldSrcURL: %w", err) + } + return oldValue.SrcURL, nil +} + +// ClearSrcURL clears the value of the "src_url" field. +func (m *PaymentOrderMutation) ClearSrcURL() { + m.src_url = nil + m.clearedFields[paymentorder.FieldSrcURL] = struct{}{} +} + +// SrcURLCleared returns if the "src_url" field was cleared in this mutation. +func (m *PaymentOrderMutation) SrcURLCleared() bool { + _, ok := m.clearedFields[paymentorder.FieldSrcURL] + return ok +} + +// ResetSrcURL resets all changes to the "src_url" field. +func (m *PaymentOrderMutation) ResetSrcURL() { + m.src_url = nil + delete(m.clearedFields, paymentorder.FieldSrcURL) +} + +// SetCreatedAt sets the "created_at" field. +func (m *PaymentOrderMutation) SetCreatedAt(t time.Time) { + m.created_at = &t +} + +// CreatedAt returns the value of the "created_at" field in the mutation. +func (m *PaymentOrderMutation) CreatedAt() (r time.Time, exists bool) { + v := m.created_at + if v == nil { + return + } + return *v, true +} + +// OldCreatedAt returns the old "created_at" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldCreatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err) + } + return oldValue.CreatedAt, nil +} + +// ResetCreatedAt resets all changes to the "created_at" field. +func (m *PaymentOrderMutation) ResetCreatedAt() { + m.created_at = nil +} + +// SetUpdatedAt sets the "updated_at" field. +func (m *PaymentOrderMutation) SetUpdatedAt(t time.Time) { + m.updated_at = &t +} + +// UpdatedAt returns the value of the "updated_at" field in the mutation. +func (m *PaymentOrderMutation) UpdatedAt() (r time.Time, exists bool) { + v := m.updated_at + if v == nil { + return + } + return *v, true +} + +// OldUpdatedAt returns the old "updated_at" field's value of the PaymentOrder entity. +// If the PaymentOrder object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentOrderMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpdatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err) + } + return oldValue.UpdatedAt, nil +} + +// ResetUpdatedAt resets all changes to the "updated_at" field. +func (m *PaymentOrderMutation) ResetUpdatedAt() { + m.updated_at = nil +} + +// ClearUser clears the "user" edge to the User entity. +func (m *PaymentOrderMutation) ClearUser() { + m.cleareduser = true + m.clearedFields[paymentorder.FieldUserID] = struct{}{} +} + +// UserCleared reports if the "user" edge to the User entity was cleared. +func (m *PaymentOrderMutation) UserCleared() bool { + return m.cleareduser +} + +// UserIDs returns the "user" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// UserID instead. It exists only for internal usage by the builders. +func (m *PaymentOrderMutation) UserIDs() (ids []int64) { + if id := m.user; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetUser resets all changes to the "user" edge. +func (m *PaymentOrderMutation) ResetUser() { + m.user = nil + m.cleareduser = false +} + +// Where appends a list predicates to the PaymentOrderMutation builder. +func (m *PaymentOrderMutation) Where(ps ...predicate.PaymentOrder) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the PaymentOrderMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *PaymentOrderMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.PaymentOrder, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *PaymentOrderMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *PaymentOrderMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (PaymentOrder). +func (m *PaymentOrderMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *PaymentOrderMutation) Fields() []string { + fields := make([]string, 0, 36) + if m.user != nil { + fields = append(fields, paymentorder.FieldUserID) + } + if m.user_email != nil { + fields = append(fields, paymentorder.FieldUserEmail) + } + if m.user_name != nil { + fields = append(fields, paymentorder.FieldUserName) + } + if m.user_notes != nil { + fields = append(fields, paymentorder.FieldUserNotes) + } + if m.amount != nil { + fields = append(fields, paymentorder.FieldAmount) + } + if m.pay_amount != nil { + fields = append(fields, paymentorder.FieldPayAmount) + } + if m.fee_rate != nil { + fields = append(fields, paymentorder.FieldFeeRate) + } + if m.recharge_code != nil { + fields = append(fields, paymentorder.FieldRechargeCode) + } + if m.payment_type != nil { + fields = append(fields, paymentorder.FieldPaymentType) + } + if m.payment_trade_no != nil { + fields = append(fields, paymentorder.FieldPaymentTradeNo) + } + if m.pay_url != nil { + fields = append(fields, paymentorder.FieldPayURL) + } + if m.qr_code != nil { + fields = append(fields, paymentorder.FieldQrCode) + } + if m.qr_code_img != nil { + fields = append(fields, paymentorder.FieldQrCodeImg) + } + if m.order_type != nil { + fields = append(fields, paymentorder.FieldOrderType) + } + if m.plan_id != nil { + fields = append(fields, paymentorder.FieldPlanID) + } + if m.subscription_group_id != nil { + fields = append(fields, paymentorder.FieldSubscriptionGroupID) + } + if m.subscription_days != nil { + fields = append(fields, paymentorder.FieldSubscriptionDays) + } + if m.provider_instance_id != nil { + fields = append(fields, paymentorder.FieldProviderInstanceID) + } + if m.status != nil { + fields = append(fields, paymentorder.FieldStatus) + } + if m.refund_amount != nil { + fields = append(fields, paymentorder.FieldRefundAmount) + } + if m.refund_reason != nil { + fields = append(fields, paymentorder.FieldRefundReason) + } + if m.refund_at != nil { + fields = append(fields, paymentorder.FieldRefundAt) + } + if m.force_refund != nil { + fields = append(fields, paymentorder.FieldForceRefund) + } + if m.refund_requested_at != nil { + fields = append(fields, paymentorder.FieldRefundRequestedAt) + } + if m.refund_request_reason != nil { + fields = append(fields, paymentorder.FieldRefundRequestReason) + } + if m.refund_requested_by != nil { + fields = append(fields, paymentorder.FieldRefundRequestedBy) + } + if m.expires_at != nil { + fields = append(fields, paymentorder.FieldExpiresAt) + } + if m.paid_at != nil { + fields = append(fields, paymentorder.FieldPaidAt) + } + if m.completed_at != nil { + fields = append(fields, paymentorder.FieldCompletedAt) + } + if m.failed_at != nil { + fields = append(fields, paymentorder.FieldFailedAt) + } + if m.failed_reason != nil { + fields = append(fields, paymentorder.FieldFailedReason) + } + if m.client_ip != nil { + fields = append(fields, paymentorder.FieldClientIP) + } + if m.src_host != nil { + fields = append(fields, paymentorder.FieldSrcHost) + } + if m.src_url != nil { + fields = append(fields, paymentorder.FieldSrcURL) + } + if m.created_at != nil { + fields = append(fields, paymentorder.FieldCreatedAt) + } + if m.updated_at != nil { + fields = append(fields, paymentorder.FieldUpdatedAt) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *PaymentOrderMutation) Field(name string) (ent.Value, bool) { + switch name { + case paymentorder.FieldUserID: + return m.UserID() + case paymentorder.FieldUserEmail: + return m.UserEmail() + case paymentorder.FieldUserName: + return m.UserName() + case paymentorder.FieldUserNotes: + return m.UserNotes() + case paymentorder.FieldAmount: + return m.Amount() + case paymentorder.FieldPayAmount: + return m.PayAmount() + case paymentorder.FieldFeeRate: + return m.FeeRate() + case paymentorder.FieldRechargeCode: + return m.RechargeCode() + case paymentorder.FieldPaymentType: + return m.PaymentType() + case paymentorder.FieldPaymentTradeNo: + return m.PaymentTradeNo() + case paymentorder.FieldPayURL: + return m.PayURL() + case paymentorder.FieldQrCode: + return m.QrCode() + case paymentorder.FieldQrCodeImg: + return m.QrCodeImg() + case paymentorder.FieldOrderType: + return m.OrderType() + case paymentorder.FieldPlanID: + return m.PlanID() + case paymentorder.FieldSubscriptionGroupID: + return m.SubscriptionGroupID() + case paymentorder.FieldSubscriptionDays: + return m.SubscriptionDays() + case paymentorder.FieldProviderInstanceID: + return m.ProviderInstanceID() + case paymentorder.FieldStatus: + return m.Status() + case paymentorder.FieldRefundAmount: + return m.RefundAmount() + case paymentorder.FieldRefundReason: + return m.RefundReason() + case paymentorder.FieldRefundAt: + return m.RefundAt() + case paymentorder.FieldForceRefund: + return m.ForceRefund() + case paymentorder.FieldRefundRequestedAt: + return m.RefundRequestedAt() + case paymentorder.FieldRefundRequestReason: + return m.RefundRequestReason() + case paymentorder.FieldRefundRequestedBy: + return m.RefundRequestedBy() + case paymentorder.FieldExpiresAt: + return m.ExpiresAt() + case paymentorder.FieldPaidAt: + return m.PaidAt() + case paymentorder.FieldCompletedAt: + return m.CompletedAt() + case paymentorder.FieldFailedAt: + return m.FailedAt() + case paymentorder.FieldFailedReason: + return m.FailedReason() + case paymentorder.FieldClientIP: + return m.ClientIP() + case paymentorder.FieldSrcHost: + return m.SrcHost() + case paymentorder.FieldSrcURL: + return m.SrcURL() + case paymentorder.FieldCreatedAt: + return m.CreatedAt() + case paymentorder.FieldUpdatedAt: + return m.UpdatedAt() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *PaymentOrderMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case paymentorder.FieldUserID: + return m.OldUserID(ctx) + case paymentorder.FieldUserEmail: + return m.OldUserEmail(ctx) + case paymentorder.FieldUserName: + return m.OldUserName(ctx) + case paymentorder.FieldUserNotes: + return m.OldUserNotes(ctx) + case paymentorder.FieldAmount: + return m.OldAmount(ctx) + case paymentorder.FieldPayAmount: + return m.OldPayAmount(ctx) + case paymentorder.FieldFeeRate: + return m.OldFeeRate(ctx) + case paymentorder.FieldRechargeCode: + return m.OldRechargeCode(ctx) + case paymentorder.FieldPaymentType: + return m.OldPaymentType(ctx) + case paymentorder.FieldPaymentTradeNo: + return m.OldPaymentTradeNo(ctx) + case paymentorder.FieldPayURL: + return m.OldPayURL(ctx) + case paymentorder.FieldQrCode: + return m.OldQrCode(ctx) + case paymentorder.FieldQrCodeImg: + return m.OldQrCodeImg(ctx) + case paymentorder.FieldOrderType: + return m.OldOrderType(ctx) + case paymentorder.FieldPlanID: + return m.OldPlanID(ctx) + case paymentorder.FieldSubscriptionGroupID: + return m.OldSubscriptionGroupID(ctx) + case paymentorder.FieldSubscriptionDays: + return m.OldSubscriptionDays(ctx) + case paymentorder.FieldProviderInstanceID: + return m.OldProviderInstanceID(ctx) + case paymentorder.FieldStatus: + return m.OldStatus(ctx) + case paymentorder.FieldRefundAmount: + return m.OldRefundAmount(ctx) + case paymentorder.FieldRefundReason: + return m.OldRefundReason(ctx) + case paymentorder.FieldRefundAt: + return m.OldRefundAt(ctx) + case paymentorder.FieldForceRefund: + return m.OldForceRefund(ctx) + case paymentorder.FieldRefundRequestedAt: + return m.OldRefundRequestedAt(ctx) + case paymentorder.FieldRefundRequestReason: + return m.OldRefundRequestReason(ctx) + case paymentorder.FieldRefundRequestedBy: + return m.OldRefundRequestedBy(ctx) + case paymentorder.FieldExpiresAt: + return m.OldExpiresAt(ctx) + case paymentorder.FieldPaidAt: + return m.OldPaidAt(ctx) + case paymentorder.FieldCompletedAt: + return m.OldCompletedAt(ctx) + case paymentorder.FieldFailedAt: + return m.OldFailedAt(ctx) + case paymentorder.FieldFailedReason: + return m.OldFailedReason(ctx) + case paymentorder.FieldClientIP: + return m.OldClientIP(ctx) + case paymentorder.FieldSrcHost: + return m.OldSrcHost(ctx) + case paymentorder.FieldSrcURL: + return m.OldSrcURL(ctx) + case paymentorder.FieldCreatedAt: + return m.OldCreatedAt(ctx) + case paymentorder.FieldUpdatedAt: + return m.OldUpdatedAt(ctx) + } + return nil, fmt.Errorf("unknown PaymentOrder field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *PaymentOrderMutation) SetField(name string, value ent.Value) error { + switch name { + case paymentorder.FieldUserID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUserID(v) + return nil + case paymentorder.FieldUserEmail: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUserEmail(v) + return nil + case paymentorder.FieldUserName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUserName(v) + return nil + case paymentorder.FieldUserNotes: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUserNotes(v) + return nil + case paymentorder.FieldAmount: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAmount(v) + return nil + case paymentorder.FieldPayAmount: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetPayAmount(v) + return nil + case paymentorder.FieldFeeRate: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetFeeRate(v) + return nil + case paymentorder.FieldRechargeCode: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRechargeCode(v) + return nil + case paymentorder.FieldPaymentType: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetPaymentType(v) + return nil + case paymentorder.FieldPaymentTradeNo: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetPaymentTradeNo(v) + return nil + case paymentorder.FieldPayURL: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetPayURL(v) + return nil + case paymentorder.FieldQrCode: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetQrCode(v) + return nil + case paymentorder.FieldQrCodeImg: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetQrCodeImg(v) + return nil + case paymentorder.FieldOrderType: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOrderType(v) + return nil + case paymentorder.FieldPlanID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetPlanID(v) + return nil + case paymentorder.FieldSubscriptionGroupID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetSubscriptionGroupID(v) + return nil + case paymentorder.FieldSubscriptionDays: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetSubscriptionDays(v) + return nil + case paymentorder.FieldProviderInstanceID: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetProviderInstanceID(v) + return nil + case paymentorder.FieldStatus: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetStatus(v) + return nil + case paymentorder.FieldRefundAmount: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRefundAmount(v) + return nil + case paymentorder.FieldRefundReason: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRefundReason(v) + return nil + case paymentorder.FieldRefundAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRefundAt(v) + return nil + case paymentorder.FieldForceRefund: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetForceRefund(v) + return nil + case paymentorder.FieldRefundRequestedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRefundRequestedAt(v) + return nil + case paymentorder.FieldRefundRequestReason: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRefundRequestReason(v) + return nil + case paymentorder.FieldRefundRequestedBy: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRefundRequestedBy(v) + return nil + case paymentorder.FieldExpiresAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetExpiresAt(v) + return nil + case paymentorder.FieldPaidAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetPaidAt(v) + return nil + case paymentorder.FieldCompletedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCompletedAt(v) + return nil + case paymentorder.FieldFailedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetFailedAt(v) + return nil + case paymentorder.FieldFailedReason: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetFailedReason(v) + return nil + case paymentorder.FieldClientIP: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetClientIP(v) + return nil + case paymentorder.FieldSrcHost: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetSrcHost(v) + return nil + case paymentorder.FieldSrcURL: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetSrcURL(v) + return nil + case paymentorder.FieldCreatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCreatedAt(v) + return nil + case paymentorder.FieldUpdatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpdatedAt(v) + return nil + } + return fmt.Errorf("unknown PaymentOrder field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *PaymentOrderMutation) AddedFields() []string { + var fields []string + if m.addamount != nil { + fields = append(fields, paymentorder.FieldAmount) + } + if m.addpay_amount != nil { + fields = append(fields, paymentorder.FieldPayAmount) + } + if m.addfee_rate != nil { + fields = append(fields, paymentorder.FieldFeeRate) + } + if m.addplan_id != nil { + fields = append(fields, paymentorder.FieldPlanID) + } + if m.addsubscription_group_id != nil { + fields = append(fields, paymentorder.FieldSubscriptionGroupID) + } + if m.addsubscription_days != nil { + fields = append(fields, paymentorder.FieldSubscriptionDays) + } + if m.addrefund_amount != nil { + fields = append(fields, paymentorder.FieldRefundAmount) + } + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *PaymentOrderMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case paymentorder.FieldAmount: + return m.AddedAmount() + case paymentorder.FieldPayAmount: + return m.AddedPayAmount() + case paymentorder.FieldFeeRate: + return m.AddedFeeRate() + case paymentorder.FieldPlanID: + return m.AddedPlanID() + case paymentorder.FieldSubscriptionGroupID: + return m.AddedSubscriptionGroupID() + case paymentorder.FieldSubscriptionDays: + return m.AddedSubscriptionDays() + case paymentorder.FieldRefundAmount: + return m.AddedRefundAmount() + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *PaymentOrderMutation) AddField(name string, value ent.Value) error { + switch name { + case paymentorder.FieldAmount: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddAmount(v) + return nil + case paymentorder.FieldPayAmount: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddPayAmount(v) + return nil + case paymentorder.FieldFeeRate: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddFeeRate(v) + return nil + case paymentorder.FieldPlanID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddPlanID(v) + return nil + case paymentorder.FieldSubscriptionGroupID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddSubscriptionGroupID(v) + return nil + case paymentorder.FieldSubscriptionDays: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddSubscriptionDays(v) + return nil + case paymentorder.FieldRefundAmount: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddRefundAmount(v) + return nil + } + return fmt.Errorf("unknown PaymentOrder numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *PaymentOrderMutation) ClearedFields() []string { + var fields []string + if m.FieldCleared(paymentorder.FieldUserNotes) { + fields = append(fields, paymentorder.FieldUserNotes) + } + if m.FieldCleared(paymentorder.FieldPayURL) { + fields = append(fields, paymentorder.FieldPayURL) + } + if m.FieldCleared(paymentorder.FieldQrCode) { + fields = append(fields, paymentorder.FieldQrCode) + } + if m.FieldCleared(paymentorder.FieldQrCodeImg) { + fields = append(fields, paymentorder.FieldQrCodeImg) + } + if m.FieldCleared(paymentorder.FieldPlanID) { + fields = append(fields, paymentorder.FieldPlanID) + } + if m.FieldCleared(paymentorder.FieldSubscriptionGroupID) { + fields = append(fields, paymentorder.FieldSubscriptionGroupID) + } + if m.FieldCleared(paymentorder.FieldSubscriptionDays) { + fields = append(fields, paymentorder.FieldSubscriptionDays) + } + if m.FieldCleared(paymentorder.FieldProviderInstanceID) { + fields = append(fields, paymentorder.FieldProviderInstanceID) + } + if m.FieldCleared(paymentorder.FieldRefundReason) { + fields = append(fields, paymentorder.FieldRefundReason) + } + if m.FieldCleared(paymentorder.FieldRefundAt) { + fields = append(fields, paymentorder.FieldRefundAt) + } + if m.FieldCleared(paymentorder.FieldRefundRequestedAt) { + fields = append(fields, paymentorder.FieldRefundRequestedAt) + } + if m.FieldCleared(paymentorder.FieldRefundRequestReason) { + fields = append(fields, paymentorder.FieldRefundRequestReason) + } + if m.FieldCleared(paymentorder.FieldRefundRequestedBy) { + fields = append(fields, paymentorder.FieldRefundRequestedBy) + } + if m.FieldCleared(paymentorder.FieldPaidAt) { + fields = append(fields, paymentorder.FieldPaidAt) + } + if m.FieldCleared(paymentorder.FieldCompletedAt) { + fields = append(fields, paymentorder.FieldCompletedAt) + } + if m.FieldCleared(paymentorder.FieldFailedAt) { + fields = append(fields, paymentorder.FieldFailedAt) + } + if m.FieldCleared(paymentorder.FieldFailedReason) { + fields = append(fields, paymentorder.FieldFailedReason) + } + if m.FieldCleared(paymentorder.FieldSrcURL) { + fields = append(fields, paymentorder.FieldSrcURL) + } + return fields +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *PaymentOrderMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *PaymentOrderMutation) ClearField(name string) error { + switch name { + case paymentorder.FieldUserNotes: + m.ClearUserNotes() + return nil + case paymentorder.FieldPayURL: + m.ClearPayURL() + return nil + case paymentorder.FieldQrCode: + m.ClearQrCode() + return nil + case paymentorder.FieldQrCodeImg: + m.ClearQrCodeImg() + return nil + case paymentorder.FieldPlanID: + m.ClearPlanID() + return nil + case paymentorder.FieldSubscriptionGroupID: + m.ClearSubscriptionGroupID() + return nil + case paymentorder.FieldSubscriptionDays: + m.ClearSubscriptionDays() + return nil + case paymentorder.FieldProviderInstanceID: + m.ClearProviderInstanceID() + return nil + case paymentorder.FieldRefundReason: + m.ClearRefundReason() + return nil + case paymentorder.FieldRefundAt: + m.ClearRefundAt() + return nil + case paymentorder.FieldRefundRequestedAt: + m.ClearRefundRequestedAt() + return nil + case paymentorder.FieldRefundRequestReason: + m.ClearRefundRequestReason() + return nil + case paymentorder.FieldRefundRequestedBy: + m.ClearRefundRequestedBy() + return nil + case paymentorder.FieldPaidAt: + m.ClearPaidAt() + return nil + case paymentorder.FieldCompletedAt: + m.ClearCompletedAt() + return nil + case paymentorder.FieldFailedAt: + m.ClearFailedAt() + return nil + case paymentorder.FieldFailedReason: + m.ClearFailedReason() + return nil + case paymentorder.FieldSrcURL: + m.ClearSrcURL() + return nil + } + return fmt.Errorf("unknown PaymentOrder nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *PaymentOrderMutation) ResetField(name string) error { + switch name { + case paymentorder.FieldUserID: + m.ResetUserID() + return nil + case paymentorder.FieldUserEmail: + m.ResetUserEmail() + return nil + case paymentorder.FieldUserName: + m.ResetUserName() + return nil + case paymentorder.FieldUserNotes: + m.ResetUserNotes() + return nil + case paymentorder.FieldAmount: + m.ResetAmount() + return nil + case paymentorder.FieldPayAmount: + m.ResetPayAmount() + return nil + case paymentorder.FieldFeeRate: + m.ResetFeeRate() + return nil + case paymentorder.FieldRechargeCode: + m.ResetRechargeCode() + return nil + case paymentorder.FieldPaymentType: + m.ResetPaymentType() + return nil + case paymentorder.FieldPaymentTradeNo: + m.ResetPaymentTradeNo() + return nil + case paymentorder.FieldPayURL: + m.ResetPayURL() + return nil + case paymentorder.FieldQrCode: + m.ResetQrCode() + return nil + case paymentorder.FieldQrCodeImg: + m.ResetQrCodeImg() + return nil + case paymentorder.FieldOrderType: + m.ResetOrderType() + return nil + case paymentorder.FieldPlanID: + m.ResetPlanID() + return nil + case paymentorder.FieldSubscriptionGroupID: + m.ResetSubscriptionGroupID() + return nil + case paymentorder.FieldSubscriptionDays: + m.ResetSubscriptionDays() + return nil + case paymentorder.FieldProviderInstanceID: + m.ResetProviderInstanceID() + return nil + case paymentorder.FieldStatus: + m.ResetStatus() + return nil + case paymentorder.FieldRefundAmount: + m.ResetRefundAmount() + return nil + case paymentorder.FieldRefundReason: + m.ResetRefundReason() + return nil + case paymentorder.FieldRefundAt: + m.ResetRefundAt() + return nil + case paymentorder.FieldForceRefund: + m.ResetForceRefund() + return nil + case paymentorder.FieldRefundRequestedAt: + m.ResetRefundRequestedAt() + return nil + case paymentorder.FieldRefundRequestReason: + m.ResetRefundRequestReason() + return nil + case paymentorder.FieldRefundRequestedBy: + m.ResetRefundRequestedBy() + return nil + case paymentorder.FieldExpiresAt: + m.ResetExpiresAt() + return nil + case paymentorder.FieldPaidAt: + m.ResetPaidAt() + return nil + case paymentorder.FieldCompletedAt: + m.ResetCompletedAt() + return nil + case paymentorder.FieldFailedAt: + m.ResetFailedAt() + return nil + case paymentorder.FieldFailedReason: + m.ResetFailedReason() + return nil + case paymentorder.FieldClientIP: + m.ResetClientIP() + return nil + case paymentorder.FieldSrcHost: + m.ResetSrcHost() + return nil + case paymentorder.FieldSrcURL: + m.ResetSrcURL() + return nil + case paymentorder.FieldCreatedAt: + m.ResetCreatedAt() + return nil + case paymentorder.FieldUpdatedAt: + m.ResetUpdatedAt() + return nil + } + return fmt.Errorf("unknown PaymentOrder field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *PaymentOrderMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.user != nil { + edges = append(edges, paymentorder.EdgeUser) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *PaymentOrderMutation) AddedIDs(name string) []ent.Value { + switch name { + case paymentorder.EdgeUser: + if id := m.user; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *PaymentOrderMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *PaymentOrderMutation) RemovedIDs(name string) []ent.Value { + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *PaymentOrderMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.cleareduser { + edges = append(edges, paymentorder.EdgeUser) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *PaymentOrderMutation) EdgeCleared(name string) bool { + switch name { + case paymentorder.EdgeUser: + return m.cleareduser + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *PaymentOrderMutation) ClearEdge(name string) error { + switch name { + case paymentorder.EdgeUser: + m.ClearUser() + return nil + } + return fmt.Errorf("unknown PaymentOrder unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *PaymentOrderMutation) ResetEdge(name string) error { + switch name { + case paymentorder.EdgeUser: + m.ResetUser() + return nil + } + return fmt.Errorf("unknown PaymentOrder edge %s", name) +} + +// PaymentProviderInstanceMutation represents an operation that mutates the PaymentProviderInstance nodes in the graph. +type PaymentProviderInstanceMutation struct { + config + op Op + typ string + id *int64 + provider_key *string + name *string + _config *string + supported_types *string + enabled *bool + sort_order *int + addsort_order *int + limits *string + refund_enabled *bool + created_at *time.Time + updated_at *time.Time + clearedFields map[string]struct{} + done bool + oldValue func(context.Context) (*PaymentProviderInstance, error) + predicates []predicate.PaymentProviderInstance +} + +var _ ent.Mutation = (*PaymentProviderInstanceMutation)(nil) + +// paymentproviderinstanceOption allows management of the mutation configuration using functional options. +type paymentproviderinstanceOption func(*PaymentProviderInstanceMutation) + +// newPaymentProviderInstanceMutation creates new mutation for the PaymentProviderInstance entity. +func newPaymentProviderInstanceMutation(c config, op Op, opts ...paymentproviderinstanceOption) *PaymentProviderInstanceMutation { + m := &PaymentProviderInstanceMutation{ + config: c, + op: op, + typ: TypePaymentProviderInstance, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withPaymentProviderInstanceID sets the ID field of the mutation. +func withPaymentProviderInstanceID(id int64) paymentproviderinstanceOption { + return func(m *PaymentProviderInstanceMutation) { + var ( + err error + once sync.Once + value *PaymentProviderInstance + ) + m.oldValue = func(ctx context.Context) (*PaymentProviderInstance, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().PaymentProviderInstance.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withPaymentProviderInstance sets the old PaymentProviderInstance of the mutation. +func withPaymentProviderInstance(node *PaymentProviderInstance) paymentproviderinstanceOption { + return func(m *PaymentProviderInstanceMutation) { + m.oldValue = func(context.Context) (*PaymentProviderInstance, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m PaymentProviderInstanceMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m PaymentProviderInstanceMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *PaymentProviderInstanceMutation) ID() (id int64, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *PaymentProviderInstanceMutation) IDs(ctx context.Context) ([]int64, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []int64{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().PaymentProviderInstance.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetProviderKey sets the "provider_key" field. +func (m *PaymentProviderInstanceMutation) SetProviderKey(s string) { + m.provider_key = &s +} + +// ProviderKey returns the value of the "provider_key" field in the mutation. +func (m *PaymentProviderInstanceMutation) ProviderKey() (r string, exists bool) { + v := m.provider_key + if v == nil { + return + } + return *v, true +} + +// OldProviderKey returns the old "provider_key" field's value of the PaymentProviderInstance entity. +// If the PaymentProviderInstance object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentProviderInstanceMutation) OldProviderKey(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldProviderKey is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldProviderKey requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldProviderKey: %w", err) + } + return oldValue.ProviderKey, nil +} + +// ResetProviderKey resets all changes to the "provider_key" field. +func (m *PaymentProviderInstanceMutation) ResetProviderKey() { + m.provider_key = nil +} + +// SetName sets the "name" field. +func (m *PaymentProviderInstanceMutation) SetName(s string) { + m.name = &s +} + +// Name returns the value of the "name" field in the mutation. +func (m *PaymentProviderInstanceMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// OldName returns the old "name" field's value of the PaymentProviderInstance entity. +// If the PaymentProviderInstance object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentProviderInstanceMutation) OldName(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldName is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldName requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldName: %w", err) + } + return oldValue.Name, nil +} + +// ResetName resets all changes to the "name" field. +func (m *PaymentProviderInstanceMutation) ResetName() { + m.name = nil +} + +// SetConfig sets the "config" field. +func (m *PaymentProviderInstanceMutation) SetConfig(s string) { + m._config = &s +} + +// Config returns the value of the "config" field in the mutation. +func (m *PaymentProviderInstanceMutation) Config() (r string, exists bool) { + v := m._config + if v == nil { + return + } + return *v, true +} + +// OldConfig returns the old "config" field's value of the PaymentProviderInstance entity. +// If the PaymentProviderInstance object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentProviderInstanceMutation) OldConfig(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldConfig is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldConfig requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldConfig: %w", err) + } + return oldValue.Config, nil +} + +// ResetConfig resets all changes to the "config" field. +func (m *PaymentProviderInstanceMutation) ResetConfig() { + m._config = nil +} + +// SetSupportedTypes sets the "supported_types" field. +func (m *PaymentProviderInstanceMutation) SetSupportedTypes(s string) { + m.supported_types = &s +} + +// SupportedTypes returns the value of the "supported_types" field in the mutation. +func (m *PaymentProviderInstanceMutation) SupportedTypes() (r string, exists bool) { + v := m.supported_types + if v == nil { + return + } + return *v, true +} + +// OldSupportedTypes returns the old "supported_types" field's value of the PaymentProviderInstance entity. +// If the PaymentProviderInstance object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentProviderInstanceMutation) OldSupportedTypes(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldSupportedTypes is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldSupportedTypes requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldSupportedTypes: %w", err) + } + return oldValue.SupportedTypes, nil +} + +// ResetSupportedTypes resets all changes to the "supported_types" field. +func (m *PaymentProviderInstanceMutation) ResetSupportedTypes() { + m.supported_types = nil +} + +// SetEnabled sets the "enabled" field. +func (m *PaymentProviderInstanceMutation) SetEnabled(b bool) { + m.enabled = &b +} + +// Enabled returns the value of the "enabled" field in the mutation. +func (m *PaymentProviderInstanceMutation) Enabled() (r bool, exists bool) { + v := m.enabled + if v == nil { + return + } + return *v, true +} + +// OldEnabled returns the old "enabled" field's value of the PaymentProviderInstance entity. +// If the PaymentProviderInstance object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentProviderInstanceMutation) OldEnabled(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldEnabled is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldEnabled requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldEnabled: %w", err) + } + return oldValue.Enabled, nil +} + +// ResetEnabled resets all changes to the "enabled" field. +func (m *PaymentProviderInstanceMutation) ResetEnabled() { + m.enabled = nil +} + +// SetSortOrder sets the "sort_order" field. +func (m *PaymentProviderInstanceMutation) SetSortOrder(i int) { + m.sort_order = &i + m.addsort_order = nil +} + +// SortOrder returns the value of the "sort_order" field in the mutation. +func (m *PaymentProviderInstanceMutation) SortOrder() (r int, exists bool) { + v := m.sort_order + if v == nil { + return + } + return *v, true +} + +// OldSortOrder returns the old "sort_order" field's value of the PaymentProviderInstance entity. +// If the PaymentProviderInstance object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentProviderInstanceMutation) OldSortOrder(ctx context.Context) (v int, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldSortOrder is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldSortOrder requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldSortOrder: %w", err) + } + return oldValue.SortOrder, nil +} + +// AddSortOrder adds i to the "sort_order" field. +func (m *PaymentProviderInstanceMutation) AddSortOrder(i int) { + if m.addsort_order != nil { + *m.addsort_order += i + } else { + m.addsort_order = &i + } +} + +// AddedSortOrder returns the value that was added to the "sort_order" field in this mutation. +func (m *PaymentProviderInstanceMutation) AddedSortOrder() (r int, exists bool) { + v := m.addsort_order + if v == nil { + return + } + return *v, true +} + +// ResetSortOrder resets all changes to the "sort_order" field. +func (m *PaymentProviderInstanceMutation) ResetSortOrder() { + m.sort_order = nil + m.addsort_order = nil +} + +// SetLimits sets the "limits" field. +func (m *PaymentProviderInstanceMutation) SetLimits(s string) { + m.limits = &s +} + +// Limits returns the value of the "limits" field in the mutation. +func (m *PaymentProviderInstanceMutation) Limits() (r string, exists bool) { + v := m.limits + if v == nil { + return + } + return *v, true +} + +// OldLimits returns the old "limits" field's value of the PaymentProviderInstance entity. +// If the PaymentProviderInstance object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentProviderInstanceMutation) OldLimits(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldLimits is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldLimits requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldLimits: %w", err) + } + return oldValue.Limits, nil +} + +// ResetLimits resets all changes to the "limits" field. +func (m *PaymentProviderInstanceMutation) ResetLimits() { + m.limits = nil +} + +// SetRefundEnabled sets the "refund_enabled" field. +func (m *PaymentProviderInstanceMutation) SetRefundEnabled(b bool) { + m.refund_enabled = &b +} + +// RefundEnabled returns the value of the "refund_enabled" field in the mutation. +func (m *PaymentProviderInstanceMutation) RefundEnabled() (r bool, exists bool) { + v := m.refund_enabled + if v == nil { + return + } + return *v, true +} + +// OldRefundEnabled returns the old "refund_enabled" field's value of the PaymentProviderInstance entity. +// If the PaymentProviderInstance object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentProviderInstanceMutation) OldRefundEnabled(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldRefundEnabled is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldRefundEnabled requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRefundEnabled: %w", err) + } + return oldValue.RefundEnabled, nil +} + +// ResetRefundEnabled resets all changes to the "refund_enabled" field. +func (m *PaymentProviderInstanceMutation) ResetRefundEnabled() { + m.refund_enabled = nil +} + +// SetCreatedAt sets the "created_at" field. +func (m *PaymentProviderInstanceMutation) SetCreatedAt(t time.Time) { + m.created_at = &t +} + +// CreatedAt returns the value of the "created_at" field in the mutation. +func (m *PaymentProviderInstanceMutation) CreatedAt() (r time.Time, exists bool) { + v := m.created_at + if v == nil { + return + } + return *v, true +} + +// OldCreatedAt returns the old "created_at" field's value of the PaymentProviderInstance entity. +// If the PaymentProviderInstance object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentProviderInstanceMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldCreatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err) + } + return oldValue.CreatedAt, nil +} + +// ResetCreatedAt resets all changes to the "created_at" field. +func (m *PaymentProviderInstanceMutation) ResetCreatedAt() { + m.created_at = nil +} + +// SetUpdatedAt sets the "updated_at" field. +func (m *PaymentProviderInstanceMutation) SetUpdatedAt(t time.Time) { + m.updated_at = &t +} + +// UpdatedAt returns the value of the "updated_at" field in the mutation. +func (m *PaymentProviderInstanceMutation) UpdatedAt() (r time.Time, exists bool) { + v := m.updated_at + if v == nil { + return + } + return *v, true +} + +// OldUpdatedAt returns the old "updated_at" field's value of the PaymentProviderInstance entity. +// If the PaymentProviderInstance object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *PaymentProviderInstanceMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpdatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err) + } + return oldValue.UpdatedAt, nil +} + +// ResetUpdatedAt resets all changes to the "updated_at" field. +func (m *PaymentProviderInstanceMutation) ResetUpdatedAt() { + m.updated_at = nil +} + +// Where appends a list predicates to the PaymentProviderInstanceMutation builder. +func (m *PaymentProviderInstanceMutation) Where(ps ...predicate.PaymentProviderInstance) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the PaymentProviderInstanceMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *PaymentProviderInstanceMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.PaymentProviderInstance, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *PaymentProviderInstanceMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *PaymentProviderInstanceMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (PaymentProviderInstance). +func (m *PaymentProviderInstanceMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *PaymentProviderInstanceMutation) Fields() []string { + fields := make([]string, 0, 10) + if m.provider_key != nil { + fields = append(fields, paymentproviderinstance.FieldProviderKey) + } + if m.name != nil { + fields = append(fields, paymentproviderinstance.FieldName) + } + if m._config != nil { + fields = append(fields, paymentproviderinstance.FieldConfig) + } + if m.supported_types != nil { + fields = append(fields, paymentproviderinstance.FieldSupportedTypes) + } + if m.enabled != nil { + fields = append(fields, paymentproviderinstance.FieldEnabled) + } + if m.sort_order != nil { + fields = append(fields, paymentproviderinstance.FieldSortOrder) + } + if m.limits != nil { + fields = append(fields, paymentproviderinstance.FieldLimits) + } + if m.refund_enabled != nil { + fields = append(fields, paymentproviderinstance.FieldRefundEnabled) + } + if m.created_at != nil { + fields = append(fields, paymentproviderinstance.FieldCreatedAt) + } + if m.updated_at != nil { + fields = append(fields, paymentproviderinstance.FieldUpdatedAt) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *PaymentProviderInstanceMutation) Field(name string) (ent.Value, bool) { + switch name { + case paymentproviderinstance.FieldProviderKey: + return m.ProviderKey() + case paymentproviderinstance.FieldName: + return m.Name() + case paymentproviderinstance.FieldConfig: + return m.Config() + case paymentproviderinstance.FieldSupportedTypes: + return m.SupportedTypes() + case paymentproviderinstance.FieldEnabled: + return m.Enabled() + case paymentproviderinstance.FieldSortOrder: + return m.SortOrder() + case paymentproviderinstance.FieldLimits: + return m.Limits() + case paymentproviderinstance.FieldRefundEnabled: + return m.RefundEnabled() + case paymentproviderinstance.FieldCreatedAt: + return m.CreatedAt() + case paymentproviderinstance.FieldUpdatedAt: + return m.UpdatedAt() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *PaymentProviderInstanceMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case paymentproviderinstance.FieldProviderKey: + return m.OldProviderKey(ctx) + case paymentproviderinstance.FieldName: + return m.OldName(ctx) + case paymentproviderinstance.FieldConfig: + return m.OldConfig(ctx) + case paymentproviderinstance.FieldSupportedTypes: + return m.OldSupportedTypes(ctx) + case paymentproviderinstance.FieldEnabled: + return m.OldEnabled(ctx) + case paymentproviderinstance.FieldSortOrder: + return m.OldSortOrder(ctx) + case paymentproviderinstance.FieldLimits: + return m.OldLimits(ctx) + case paymentproviderinstance.FieldRefundEnabled: + return m.OldRefundEnabled(ctx) + case paymentproviderinstance.FieldCreatedAt: + return m.OldCreatedAt(ctx) + case paymentproviderinstance.FieldUpdatedAt: + return m.OldUpdatedAt(ctx) + } + return nil, fmt.Errorf("unknown PaymentProviderInstance field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *PaymentProviderInstanceMutation) SetField(name string, value ent.Value) error { + switch name { + case paymentproviderinstance.FieldProviderKey: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetProviderKey(v) + return nil + case paymentproviderinstance.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case paymentproviderinstance.FieldConfig: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetConfig(v) + return nil + case paymentproviderinstance.FieldSupportedTypes: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetSupportedTypes(v) + return nil + case paymentproviderinstance.FieldEnabled: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetEnabled(v) + return nil + case paymentproviderinstance.FieldSortOrder: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetSortOrder(v) + return nil + case paymentproviderinstance.FieldLimits: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetLimits(v) + return nil + case paymentproviderinstance.FieldRefundEnabled: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRefundEnabled(v) + return nil + case paymentproviderinstance.FieldCreatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCreatedAt(v) + return nil + case paymentproviderinstance.FieldUpdatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpdatedAt(v) + return nil + } + return fmt.Errorf("unknown PaymentProviderInstance field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *PaymentProviderInstanceMutation) AddedFields() []string { + var fields []string + if m.addsort_order != nil { + fields = append(fields, paymentproviderinstance.FieldSortOrder) + } + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *PaymentProviderInstanceMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case paymentproviderinstance.FieldSortOrder: + return m.AddedSortOrder() + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *PaymentProviderInstanceMutation) AddField(name string, value ent.Value) error { + switch name { + case paymentproviderinstance.FieldSortOrder: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddSortOrder(v) + return nil + } + return fmt.Errorf("unknown PaymentProviderInstance numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *PaymentProviderInstanceMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *PaymentProviderInstanceMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *PaymentProviderInstanceMutation) ClearField(name string) error { + return fmt.Errorf("unknown PaymentProviderInstance nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *PaymentProviderInstanceMutation) ResetField(name string) error { + switch name { + case paymentproviderinstance.FieldProviderKey: + m.ResetProviderKey() + return nil + case paymentproviderinstance.FieldName: + m.ResetName() + return nil + case paymentproviderinstance.FieldConfig: + m.ResetConfig() + return nil + case paymentproviderinstance.FieldSupportedTypes: + m.ResetSupportedTypes() + return nil + case paymentproviderinstance.FieldEnabled: + m.ResetEnabled() + return nil + case paymentproviderinstance.FieldSortOrder: + m.ResetSortOrder() + return nil + case paymentproviderinstance.FieldLimits: + m.ResetLimits() + return nil + case paymentproviderinstance.FieldRefundEnabled: + m.ResetRefundEnabled() + return nil + case paymentproviderinstance.FieldCreatedAt: + m.ResetCreatedAt() + return nil + case paymentproviderinstance.FieldUpdatedAt: + m.ResetUpdatedAt() + return nil + } + return fmt.Errorf("unknown PaymentProviderInstance field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *PaymentProviderInstanceMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *PaymentProviderInstanceMutation) AddedIDs(name string) []ent.Value { + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *PaymentProviderInstanceMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *PaymentProviderInstanceMutation) RemovedIDs(name string) []ent.Value { + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *PaymentProviderInstanceMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *PaymentProviderInstanceMutation) EdgeCleared(name string) bool { + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *PaymentProviderInstanceMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown PaymentProviderInstance unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *PaymentProviderInstanceMutation) ResetEdge(name string) error { + return fmt.Errorf("unknown PaymentProviderInstance edge %s", name) +} + // PromoCodeMutation represents an operation that mutates the PromoCode nodes in the graph. type PromoCodeMutation struct { config @@ -16743,6 +20993,1171 @@ func (m *SettingMutation) ResetEdge(name string) error { return fmt.Errorf("unknown Setting edge %s", name) } +// SubscriptionPlanMutation represents an operation that mutates the SubscriptionPlan nodes in the graph. +type SubscriptionPlanMutation struct { + config + op Op + typ string + id *int64 + group_id *int64 + addgroup_id *int64 + name *string + description *string + price *float64 + addprice *float64 + original_price *float64 + addoriginal_price *float64 + validity_days *int + addvalidity_days *int + validity_unit *string + features *string + product_name *string + for_sale *bool + sort_order *int + addsort_order *int + created_at *time.Time + updated_at *time.Time + clearedFields map[string]struct{} + done bool + oldValue func(context.Context) (*SubscriptionPlan, error) + predicates []predicate.SubscriptionPlan +} + +var _ ent.Mutation = (*SubscriptionPlanMutation)(nil) + +// subscriptionplanOption allows management of the mutation configuration using functional options. +type subscriptionplanOption func(*SubscriptionPlanMutation) + +// newSubscriptionPlanMutation creates new mutation for the SubscriptionPlan entity. +func newSubscriptionPlanMutation(c config, op Op, opts ...subscriptionplanOption) *SubscriptionPlanMutation { + m := &SubscriptionPlanMutation{ + config: c, + op: op, + typ: TypeSubscriptionPlan, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withSubscriptionPlanID sets the ID field of the mutation. +func withSubscriptionPlanID(id int64) subscriptionplanOption { + return func(m *SubscriptionPlanMutation) { + var ( + err error + once sync.Once + value *SubscriptionPlan + ) + m.oldValue = func(ctx context.Context) (*SubscriptionPlan, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().SubscriptionPlan.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withSubscriptionPlan sets the old SubscriptionPlan of the mutation. +func withSubscriptionPlan(node *SubscriptionPlan) subscriptionplanOption { + return func(m *SubscriptionPlanMutation) { + m.oldValue = func(context.Context) (*SubscriptionPlan, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m SubscriptionPlanMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m SubscriptionPlanMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *SubscriptionPlanMutation) ID() (id int64, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *SubscriptionPlanMutation) IDs(ctx context.Context) ([]int64, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []int64{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().SubscriptionPlan.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetGroupID sets the "group_id" field. +func (m *SubscriptionPlanMutation) SetGroupID(i int64) { + m.group_id = &i + m.addgroup_id = nil +} + +// GroupID returns the value of the "group_id" field in the mutation. +func (m *SubscriptionPlanMutation) GroupID() (r int64, exists bool) { + v := m.group_id + if v == nil { + return + } + return *v, true +} + +// OldGroupID returns the old "group_id" field's value of the SubscriptionPlan entity. +// If the SubscriptionPlan object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SubscriptionPlanMutation) OldGroupID(ctx context.Context) (v int64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldGroupID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldGroupID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldGroupID: %w", err) + } + return oldValue.GroupID, nil +} + +// AddGroupID adds i to the "group_id" field. +func (m *SubscriptionPlanMutation) AddGroupID(i int64) { + if m.addgroup_id != nil { + *m.addgroup_id += i + } else { + m.addgroup_id = &i + } +} + +// AddedGroupID returns the value that was added to the "group_id" field in this mutation. +func (m *SubscriptionPlanMutation) AddedGroupID() (r int64, exists bool) { + v := m.addgroup_id + if v == nil { + return + } + return *v, true +} + +// ResetGroupID resets all changes to the "group_id" field. +func (m *SubscriptionPlanMutation) ResetGroupID() { + m.group_id = nil + m.addgroup_id = nil +} + +// SetName sets the "name" field. +func (m *SubscriptionPlanMutation) SetName(s string) { + m.name = &s +} + +// Name returns the value of the "name" field in the mutation. +func (m *SubscriptionPlanMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// OldName returns the old "name" field's value of the SubscriptionPlan entity. +// If the SubscriptionPlan object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SubscriptionPlanMutation) OldName(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldName is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldName requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldName: %w", err) + } + return oldValue.Name, nil +} + +// ResetName resets all changes to the "name" field. +func (m *SubscriptionPlanMutation) ResetName() { + m.name = nil +} + +// SetDescription sets the "description" field. +func (m *SubscriptionPlanMutation) SetDescription(s string) { + m.description = &s +} + +// Description returns the value of the "description" field in the mutation. +func (m *SubscriptionPlanMutation) Description() (r string, exists bool) { + v := m.description + if v == nil { + return + } + return *v, true +} + +// OldDescription returns the old "description" field's value of the SubscriptionPlan entity. +// If the SubscriptionPlan object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SubscriptionPlanMutation) OldDescription(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldDescription is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldDescription requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldDescription: %w", err) + } + return oldValue.Description, nil +} + +// ResetDescription resets all changes to the "description" field. +func (m *SubscriptionPlanMutation) ResetDescription() { + m.description = nil +} + +// SetPrice sets the "price" field. +func (m *SubscriptionPlanMutation) SetPrice(f float64) { + m.price = &f + m.addprice = nil +} + +// Price returns the value of the "price" field in the mutation. +func (m *SubscriptionPlanMutation) Price() (r float64, exists bool) { + v := m.price + if v == nil { + return + } + return *v, true +} + +// OldPrice returns the old "price" field's value of the SubscriptionPlan entity. +// If the SubscriptionPlan object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SubscriptionPlanMutation) OldPrice(ctx context.Context) (v float64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldPrice is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldPrice requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldPrice: %w", err) + } + return oldValue.Price, nil +} + +// AddPrice adds f to the "price" field. +func (m *SubscriptionPlanMutation) AddPrice(f float64) { + if m.addprice != nil { + *m.addprice += f + } else { + m.addprice = &f + } +} + +// AddedPrice returns the value that was added to the "price" field in this mutation. +func (m *SubscriptionPlanMutation) AddedPrice() (r float64, exists bool) { + v := m.addprice + if v == nil { + return + } + return *v, true +} + +// ResetPrice resets all changes to the "price" field. +func (m *SubscriptionPlanMutation) ResetPrice() { + m.price = nil + m.addprice = nil +} + +// SetOriginalPrice sets the "original_price" field. +func (m *SubscriptionPlanMutation) SetOriginalPrice(f float64) { + m.original_price = &f + m.addoriginal_price = nil +} + +// OriginalPrice returns the value of the "original_price" field in the mutation. +func (m *SubscriptionPlanMutation) OriginalPrice() (r float64, exists bool) { + v := m.original_price + if v == nil { + return + } + return *v, true +} + +// OldOriginalPrice returns the old "original_price" field's value of the SubscriptionPlan entity. +// If the SubscriptionPlan object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SubscriptionPlanMutation) OldOriginalPrice(ctx context.Context) (v *float64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldOriginalPrice is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldOriginalPrice requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldOriginalPrice: %w", err) + } + return oldValue.OriginalPrice, nil +} + +// AddOriginalPrice adds f to the "original_price" field. +func (m *SubscriptionPlanMutation) AddOriginalPrice(f float64) { + if m.addoriginal_price != nil { + *m.addoriginal_price += f + } else { + m.addoriginal_price = &f + } +} + +// AddedOriginalPrice returns the value that was added to the "original_price" field in this mutation. +func (m *SubscriptionPlanMutation) AddedOriginalPrice() (r float64, exists bool) { + v := m.addoriginal_price + if v == nil { + return + } + return *v, true +} + +// ClearOriginalPrice clears the value of the "original_price" field. +func (m *SubscriptionPlanMutation) ClearOriginalPrice() { + m.original_price = nil + m.addoriginal_price = nil + m.clearedFields[subscriptionplan.FieldOriginalPrice] = struct{}{} +} + +// OriginalPriceCleared returns if the "original_price" field was cleared in this mutation. +func (m *SubscriptionPlanMutation) OriginalPriceCleared() bool { + _, ok := m.clearedFields[subscriptionplan.FieldOriginalPrice] + return ok +} + +// ResetOriginalPrice resets all changes to the "original_price" field. +func (m *SubscriptionPlanMutation) ResetOriginalPrice() { + m.original_price = nil + m.addoriginal_price = nil + delete(m.clearedFields, subscriptionplan.FieldOriginalPrice) +} + +// SetValidityDays sets the "validity_days" field. +func (m *SubscriptionPlanMutation) SetValidityDays(i int) { + m.validity_days = &i + m.addvalidity_days = nil +} + +// ValidityDays returns the value of the "validity_days" field in the mutation. +func (m *SubscriptionPlanMutation) ValidityDays() (r int, exists bool) { + v := m.validity_days + if v == nil { + return + } + return *v, true +} + +// OldValidityDays returns the old "validity_days" field's value of the SubscriptionPlan entity. +// If the SubscriptionPlan object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SubscriptionPlanMutation) OldValidityDays(ctx context.Context) (v int, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldValidityDays is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldValidityDays requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldValidityDays: %w", err) + } + return oldValue.ValidityDays, nil +} + +// AddValidityDays adds i to the "validity_days" field. +func (m *SubscriptionPlanMutation) AddValidityDays(i int) { + if m.addvalidity_days != nil { + *m.addvalidity_days += i + } else { + m.addvalidity_days = &i + } +} + +// AddedValidityDays returns the value that was added to the "validity_days" field in this mutation. +func (m *SubscriptionPlanMutation) AddedValidityDays() (r int, exists bool) { + v := m.addvalidity_days + if v == nil { + return + } + return *v, true +} + +// ResetValidityDays resets all changes to the "validity_days" field. +func (m *SubscriptionPlanMutation) ResetValidityDays() { + m.validity_days = nil + m.addvalidity_days = nil +} + +// SetValidityUnit sets the "validity_unit" field. +func (m *SubscriptionPlanMutation) SetValidityUnit(s string) { + m.validity_unit = &s +} + +// ValidityUnit returns the value of the "validity_unit" field in the mutation. +func (m *SubscriptionPlanMutation) ValidityUnit() (r string, exists bool) { + v := m.validity_unit + if v == nil { + return + } + return *v, true +} + +// OldValidityUnit returns the old "validity_unit" field's value of the SubscriptionPlan entity. +// If the SubscriptionPlan object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SubscriptionPlanMutation) OldValidityUnit(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldValidityUnit is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldValidityUnit requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldValidityUnit: %w", err) + } + return oldValue.ValidityUnit, nil +} + +// ResetValidityUnit resets all changes to the "validity_unit" field. +func (m *SubscriptionPlanMutation) ResetValidityUnit() { + m.validity_unit = nil +} + +// SetFeatures sets the "features" field. +func (m *SubscriptionPlanMutation) SetFeatures(s string) { + m.features = &s +} + +// Features returns the value of the "features" field in the mutation. +func (m *SubscriptionPlanMutation) Features() (r string, exists bool) { + v := m.features + if v == nil { + return + } + return *v, true +} + +// OldFeatures returns the old "features" field's value of the SubscriptionPlan entity. +// If the SubscriptionPlan object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SubscriptionPlanMutation) OldFeatures(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldFeatures is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldFeatures requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldFeatures: %w", err) + } + return oldValue.Features, nil +} + +// ResetFeatures resets all changes to the "features" field. +func (m *SubscriptionPlanMutation) ResetFeatures() { + m.features = nil +} + +// SetProductName sets the "product_name" field. +func (m *SubscriptionPlanMutation) SetProductName(s string) { + m.product_name = &s +} + +// ProductName returns the value of the "product_name" field in the mutation. +func (m *SubscriptionPlanMutation) ProductName() (r string, exists bool) { + v := m.product_name + if v == nil { + return + } + return *v, true +} + +// OldProductName returns the old "product_name" field's value of the SubscriptionPlan entity. +// If the SubscriptionPlan object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SubscriptionPlanMutation) OldProductName(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldProductName is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldProductName requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldProductName: %w", err) + } + return oldValue.ProductName, nil +} + +// ResetProductName resets all changes to the "product_name" field. +func (m *SubscriptionPlanMutation) ResetProductName() { + m.product_name = nil +} + +// SetForSale sets the "for_sale" field. +func (m *SubscriptionPlanMutation) SetForSale(b bool) { + m.for_sale = &b +} + +// ForSale returns the value of the "for_sale" field in the mutation. +func (m *SubscriptionPlanMutation) ForSale() (r bool, exists bool) { + v := m.for_sale + if v == nil { + return + } + return *v, true +} + +// OldForSale returns the old "for_sale" field's value of the SubscriptionPlan entity. +// If the SubscriptionPlan object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SubscriptionPlanMutation) OldForSale(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldForSale is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldForSale requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldForSale: %w", err) + } + return oldValue.ForSale, nil +} + +// ResetForSale resets all changes to the "for_sale" field. +func (m *SubscriptionPlanMutation) ResetForSale() { + m.for_sale = nil +} + +// SetSortOrder sets the "sort_order" field. +func (m *SubscriptionPlanMutation) SetSortOrder(i int) { + m.sort_order = &i + m.addsort_order = nil +} + +// SortOrder returns the value of the "sort_order" field in the mutation. +func (m *SubscriptionPlanMutation) SortOrder() (r int, exists bool) { + v := m.sort_order + if v == nil { + return + } + return *v, true +} + +// OldSortOrder returns the old "sort_order" field's value of the SubscriptionPlan entity. +// If the SubscriptionPlan object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SubscriptionPlanMutation) OldSortOrder(ctx context.Context) (v int, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldSortOrder is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldSortOrder requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldSortOrder: %w", err) + } + return oldValue.SortOrder, nil +} + +// AddSortOrder adds i to the "sort_order" field. +func (m *SubscriptionPlanMutation) AddSortOrder(i int) { + if m.addsort_order != nil { + *m.addsort_order += i + } else { + m.addsort_order = &i + } +} + +// AddedSortOrder returns the value that was added to the "sort_order" field in this mutation. +func (m *SubscriptionPlanMutation) AddedSortOrder() (r int, exists bool) { + v := m.addsort_order + if v == nil { + return + } + return *v, true +} + +// ResetSortOrder resets all changes to the "sort_order" field. +func (m *SubscriptionPlanMutation) ResetSortOrder() { + m.sort_order = nil + m.addsort_order = nil +} + +// SetCreatedAt sets the "created_at" field. +func (m *SubscriptionPlanMutation) SetCreatedAt(t time.Time) { + m.created_at = &t +} + +// CreatedAt returns the value of the "created_at" field in the mutation. +func (m *SubscriptionPlanMutation) CreatedAt() (r time.Time, exists bool) { + v := m.created_at + if v == nil { + return + } + return *v, true +} + +// OldCreatedAt returns the old "created_at" field's value of the SubscriptionPlan entity. +// If the SubscriptionPlan object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SubscriptionPlanMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldCreatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err) + } + return oldValue.CreatedAt, nil +} + +// ResetCreatedAt resets all changes to the "created_at" field. +func (m *SubscriptionPlanMutation) ResetCreatedAt() { + m.created_at = nil +} + +// SetUpdatedAt sets the "updated_at" field. +func (m *SubscriptionPlanMutation) SetUpdatedAt(t time.Time) { + m.updated_at = &t +} + +// UpdatedAt returns the value of the "updated_at" field in the mutation. +func (m *SubscriptionPlanMutation) UpdatedAt() (r time.Time, exists bool) { + v := m.updated_at + if v == nil { + return + } + return *v, true +} + +// OldUpdatedAt returns the old "updated_at" field's value of the SubscriptionPlan entity. +// If the SubscriptionPlan object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SubscriptionPlanMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpdatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err) + } + return oldValue.UpdatedAt, nil +} + +// ResetUpdatedAt resets all changes to the "updated_at" field. +func (m *SubscriptionPlanMutation) ResetUpdatedAt() { + m.updated_at = nil +} + +// Where appends a list predicates to the SubscriptionPlanMutation builder. +func (m *SubscriptionPlanMutation) Where(ps ...predicate.SubscriptionPlan) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the SubscriptionPlanMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *SubscriptionPlanMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.SubscriptionPlan, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *SubscriptionPlanMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *SubscriptionPlanMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (SubscriptionPlan). +func (m *SubscriptionPlanMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *SubscriptionPlanMutation) Fields() []string { + fields := make([]string, 0, 13) + if m.group_id != nil { + fields = append(fields, subscriptionplan.FieldGroupID) + } + if m.name != nil { + fields = append(fields, subscriptionplan.FieldName) + } + if m.description != nil { + fields = append(fields, subscriptionplan.FieldDescription) + } + if m.price != nil { + fields = append(fields, subscriptionplan.FieldPrice) + } + if m.original_price != nil { + fields = append(fields, subscriptionplan.FieldOriginalPrice) + } + if m.validity_days != nil { + fields = append(fields, subscriptionplan.FieldValidityDays) + } + if m.validity_unit != nil { + fields = append(fields, subscriptionplan.FieldValidityUnit) + } + if m.features != nil { + fields = append(fields, subscriptionplan.FieldFeatures) + } + if m.product_name != nil { + fields = append(fields, subscriptionplan.FieldProductName) + } + if m.for_sale != nil { + fields = append(fields, subscriptionplan.FieldForSale) + } + if m.sort_order != nil { + fields = append(fields, subscriptionplan.FieldSortOrder) + } + if m.created_at != nil { + fields = append(fields, subscriptionplan.FieldCreatedAt) + } + if m.updated_at != nil { + fields = append(fields, subscriptionplan.FieldUpdatedAt) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *SubscriptionPlanMutation) Field(name string) (ent.Value, bool) { + switch name { + case subscriptionplan.FieldGroupID: + return m.GroupID() + case subscriptionplan.FieldName: + return m.Name() + case subscriptionplan.FieldDescription: + return m.Description() + case subscriptionplan.FieldPrice: + return m.Price() + case subscriptionplan.FieldOriginalPrice: + return m.OriginalPrice() + case subscriptionplan.FieldValidityDays: + return m.ValidityDays() + case subscriptionplan.FieldValidityUnit: + return m.ValidityUnit() + case subscriptionplan.FieldFeatures: + return m.Features() + case subscriptionplan.FieldProductName: + return m.ProductName() + case subscriptionplan.FieldForSale: + return m.ForSale() + case subscriptionplan.FieldSortOrder: + return m.SortOrder() + case subscriptionplan.FieldCreatedAt: + return m.CreatedAt() + case subscriptionplan.FieldUpdatedAt: + return m.UpdatedAt() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *SubscriptionPlanMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case subscriptionplan.FieldGroupID: + return m.OldGroupID(ctx) + case subscriptionplan.FieldName: + return m.OldName(ctx) + case subscriptionplan.FieldDescription: + return m.OldDescription(ctx) + case subscriptionplan.FieldPrice: + return m.OldPrice(ctx) + case subscriptionplan.FieldOriginalPrice: + return m.OldOriginalPrice(ctx) + case subscriptionplan.FieldValidityDays: + return m.OldValidityDays(ctx) + case subscriptionplan.FieldValidityUnit: + return m.OldValidityUnit(ctx) + case subscriptionplan.FieldFeatures: + return m.OldFeatures(ctx) + case subscriptionplan.FieldProductName: + return m.OldProductName(ctx) + case subscriptionplan.FieldForSale: + return m.OldForSale(ctx) + case subscriptionplan.FieldSortOrder: + return m.OldSortOrder(ctx) + case subscriptionplan.FieldCreatedAt: + return m.OldCreatedAt(ctx) + case subscriptionplan.FieldUpdatedAt: + return m.OldUpdatedAt(ctx) + } + return nil, fmt.Errorf("unknown SubscriptionPlan field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *SubscriptionPlanMutation) SetField(name string, value ent.Value) error { + switch name { + case subscriptionplan.FieldGroupID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetGroupID(v) + return nil + case subscriptionplan.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case subscriptionplan.FieldDescription: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDescription(v) + return nil + case subscriptionplan.FieldPrice: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetPrice(v) + return nil + case subscriptionplan.FieldOriginalPrice: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOriginalPrice(v) + return nil + case subscriptionplan.FieldValidityDays: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetValidityDays(v) + return nil + case subscriptionplan.FieldValidityUnit: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetValidityUnit(v) + return nil + case subscriptionplan.FieldFeatures: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetFeatures(v) + return nil + case subscriptionplan.FieldProductName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetProductName(v) + return nil + case subscriptionplan.FieldForSale: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetForSale(v) + return nil + case subscriptionplan.FieldSortOrder: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetSortOrder(v) + return nil + case subscriptionplan.FieldCreatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCreatedAt(v) + return nil + case subscriptionplan.FieldUpdatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpdatedAt(v) + return nil + } + return fmt.Errorf("unknown SubscriptionPlan field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *SubscriptionPlanMutation) AddedFields() []string { + var fields []string + if m.addgroup_id != nil { + fields = append(fields, subscriptionplan.FieldGroupID) + } + if m.addprice != nil { + fields = append(fields, subscriptionplan.FieldPrice) + } + if m.addoriginal_price != nil { + fields = append(fields, subscriptionplan.FieldOriginalPrice) + } + if m.addvalidity_days != nil { + fields = append(fields, subscriptionplan.FieldValidityDays) + } + if m.addsort_order != nil { + fields = append(fields, subscriptionplan.FieldSortOrder) + } + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *SubscriptionPlanMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case subscriptionplan.FieldGroupID: + return m.AddedGroupID() + case subscriptionplan.FieldPrice: + return m.AddedPrice() + case subscriptionplan.FieldOriginalPrice: + return m.AddedOriginalPrice() + case subscriptionplan.FieldValidityDays: + return m.AddedValidityDays() + case subscriptionplan.FieldSortOrder: + return m.AddedSortOrder() + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *SubscriptionPlanMutation) AddField(name string, value ent.Value) error { + switch name { + case subscriptionplan.FieldGroupID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddGroupID(v) + return nil + case subscriptionplan.FieldPrice: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddPrice(v) + return nil + case subscriptionplan.FieldOriginalPrice: + v, ok := value.(float64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddOriginalPrice(v) + return nil + case subscriptionplan.FieldValidityDays: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddValidityDays(v) + return nil + case subscriptionplan.FieldSortOrder: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddSortOrder(v) + return nil + } + return fmt.Errorf("unknown SubscriptionPlan numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *SubscriptionPlanMutation) ClearedFields() []string { + var fields []string + if m.FieldCleared(subscriptionplan.FieldOriginalPrice) { + fields = append(fields, subscriptionplan.FieldOriginalPrice) + } + return fields +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *SubscriptionPlanMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *SubscriptionPlanMutation) ClearField(name string) error { + switch name { + case subscriptionplan.FieldOriginalPrice: + m.ClearOriginalPrice() + return nil + } + return fmt.Errorf("unknown SubscriptionPlan nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *SubscriptionPlanMutation) ResetField(name string) error { + switch name { + case subscriptionplan.FieldGroupID: + m.ResetGroupID() + return nil + case subscriptionplan.FieldName: + m.ResetName() + return nil + case subscriptionplan.FieldDescription: + m.ResetDescription() + return nil + case subscriptionplan.FieldPrice: + m.ResetPrice() + return nil + case subscriptionplan.FieldOriginalPrice: + m.ResetOriginalPrice() + return nil + case subscriptionplan.FieldValidityDays: + m.ResetValidityDays() + return nil + case subscriptionplan.FieldValidityUnit: + m.ResetValidityUnit() + return nil + case subscriptionplan.FieldFeatures: + m.ResetFeatures() + return nil + case subscriptionplan.FieldProductName: + m.ResetProductName() + return nil + case subscriptionplan.FieldForSale: + m.ResetForSale() + return nil + case subscriptionplan.FieldSortOrder: + m.ResetSortOrder() + return nil + case subscriptionplan.FieldCreatedAt: + m.ResetCreatedAt() + return nil + case subscriptionplan.FieldUpdatedAt: + m.ResetUpdatedAt() + return nil + } + return fmt.Errorf("unknown SubscriptionPlan field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *SubscriptionPlanMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *SubscriptionPlanMutation) AddedIDs(name string) []ent.Value { + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *SubscriptionPlanMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *SubscriptionPlanMutation) RemovedIDs(name string) []ent.Value { + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *SubscriptionPlanMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *SubscriptionPlanMutation) EdgeCleared(name string) bool { + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *SubscriptionPlanMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown SubscriptionPlan unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *SubscriptionPlanMutation) ResetEdge(name string) error { + return fmt.Errorf("unknown SubscriptionPlan edge %s", name) +} + // TLSFingerprintProfileMutation represents an operation that mutates the TLSFingerprintProfile nodes in the graph. type TLSFingerprintProfileMutation struct { config @@ -22661,6 +28076,9 @@ type UserMutation struct { promo_code_usages map[int64]struct{} removedpromo_code_usages map[int64]struct{} clearedpromo_code_usages bool + payment_orders map[int64]struct{} + removedpayment_orders map[int64]struct{} + clearedpayment_orders bool done bool oldValue func(context.Context) (*User, error) predicates []predicate.User @@ -23833,6 +29251,60 @@ func (m *UserMutation) ResetPromoCodeUsages() { m.removedpromo_code_usages = nil } +// AddPaymentOrderIDs adds the "payment_orders" edge to the PaymentOrder entity by ids. +func (m *UserMutation) AddPaymentOrderIDs(ids ...int64) { + if m.payment_orders == nil { + m.payment_orders = make(map[int64]struct{}) + } + for i := range ids { + m.payment_orders[ids[i]] = struct{}{} + } +} + +// ClearPaymentOrders clears the "payment_orders" edge to the PaymentOrder entity. +func (m *UserMutation) ClearPaymentOrders() { + m.clearedpayment_orders = true +} + +// PaymentOrdersCleared reports if the "payment_orders" edge to the PaymentOrder entity was cleared. +func (m *UserMutation) PaymentOrdersCleared() bool { + return m.clearedpayment_orders +} + +// RemovePaymentOrderIDs removes the "payment_orders" edge to the PaymentOrder entity by IDs. +func (m *UserMutation) RemovePaymentOrderIDs(ids ...int64) { + if m.removedpayment_orders == nil { + m.removedpayment_orders = make(map[int64]struct{}) + } + for i := range ids { + delete(m.payment_orders, ids[i]) + m.removedpayment_orders[ids[i]] = struct{}{} + } +} + +// RemovedPaymentOrders returns the removed IDs of the "payment_orders" edge to the PaymentOrder entity. +func (m *UserMutation) RemovedPaymentOrdersIDs() (ids []int64) { + for id := range m.removedpayment_orders { + ids = append(ids, id) + } + return +} + +// PaymentOrdersIDs returns the "payment_orders" edge IDs in the mutation. +func (m *UserMutation) PaymentOrdersIDs() (ids []int64) { + for id := range m.payment_orders { + ids = append(ids, id) + } + return +} + +// ResetPaymentOrders resets all changes to the "payment_orders" edge. +func (m *UserMutation) ResetPaymentOrders() { + m.payment_orders = nil + m.clearedpayment_orders = false + m.removedpayment_orders = nil +} + // Where appends a list predicates to the UserMutation builder. func (m *UserMutation) Where(ps ...predicate.User) { m.predicates = append(m.predicates, ps...) @@ -24235,7 +29707,7 @@ func (m *UserMutation) ResetField(name string) error { // AddedEdges returns all edge names that were set/added in this mutation. func (m *UserMutation) AddedEdges() []string { - edges := make([]string, 0, 9) + edges := make([]string, 0, 10) if m.api_keys != nil { edges = append(edges, user.EdgeAPIKeys) } @@ -24263,6 +29735,9 @@ func (m *UserMutation) AddedEdges() []string { if m.promo_code_usages != nil { edges = append(edges, user.EdgePromoCodeUsages) } + if m.payment_orders != nil { + edges = append(edges, user.EdgePaymentOrders) + } return edges } @@ -24324,13 +29799,19 @@ func (m *UserMutation) AddedIDs(name string) []ent.Value { ids = append(ids, id) } return ids + case user.EdgePaymentOrders: + ids := make([]ent.Value, 0, len(m.payment_orders)) + for id := range m.payment_orders { + ids = append(ids, id) + } + return ids } return nil } // RemovedEdges returns all edge names that were removed in this mutation. func (m *UserMutation) RemovedEdges() []string { - edges := make([]string, 0, 9) + edges := make([]string, 0, 10) if m.removedapi_keys != nil { edges = append(edges, user.EdgeAPIKeys) } @@ -24358,6 +29839,9 @@ func (m *UserMutation) RemovedEdges() []string { if m.removedpromo_code_usages != nil { edges = append(edges, user.EdgePromoCodeUsages) } + if m.removedpayment_orders != nil { + edges = append(edges, user.EdgePaymentOrders) + } return edges } @@ -24419,13 +29903,19 @@ func (m *UserMutation) RemovedIDs(name string) []ent.Value { ids = append(ids, id) } return ids + case user.EdgePaymentOrders: + ids := make([]ent.Value, 0, len(m.removedpayment_orders)) + for id := range m.removedpayment_orders { + ids = append(ids, id) + } + return ids } return nil } // ClearedEdges returns all edge names that were cleared in this mutation. func (m *UserMutation) ClearedEdges() []string { - edges := make([]string, 0, 9) + edges := make([]string, 0, 10) if m.clearedapi_keys { edges = append(edges, user.EdgeAPIKeys) } @@ -24453,6 +29943,9 @@ func (m *UserMutation) ClearedEdges() []string { if m.clearedpromo_code_usages { edges = append(edges, user.EdgePromoCodeUsages) } + if m.clearedpayment_orders { + edges = append(edges, user.EdgePaymentOrders) + } return edges } @@ -24478,6 +29971,8 @@ func (m *UserMutation) EdgeCleared(name string) bool { return m.clearedattribute_values case user.EdgePromoCodeUsages: return m.clearedpromo_code_usages + case user.EdgePaymentOrders: + return m.clearedpayment_orders } return false } @@ -24521,6 +30016,9 @@ func (m *UserMutation) ResetEdge(name string) error { case user.EdgePromoCodeUsages: m.ResetPromoCodeUsages() return nil + case user.EdgePaymentOrders: + m.ResetPaymentOrders() + return nil } return fmt.Errorf("unknown User edge %s", name) } diff --git a/backend/ent/paymentauditlog.go b/backend/ent/paymentauditlog.go new file mode 100644 index 0000000000..ffcdcfcd95 --- /dev/null +++ b/backend/ent/paymentauditlog.go @@ -0,0 +1,150 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "github.com/Wei-Shaw/sub2api/ent/paymentauditlog" +) + +// PaymentAuditLog is the model entity for the PaymentAuditLog schema. +type PaymentAuditLog struct { + config `json:"-"` + // ID of the ent. + ID int64 `json:"id,omitempty"` + // OrderID holds the value of the "order_id" field. + OrderID string `json:"order_id,omitempty"` + // Action holds the value of the "action" field. + Action string `json:"action,omitempty"` + // Detail holds the value of the "detail" field. + Detail string `json:"detail,omitempty"` + // Operator holds the value of the "operator" field. + Operator string `json:"operator,omitempty"` + // CreatedAt holds the value of the "created_at" field. + CreatedAt time.Time `json:"created_at,omitempty"` + selectValues sql.SelectValues +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*PaymentAuditLog) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case paymentauditlog.FieldID: + values[i] = new(sql.NullInt64) + case paymentauditlog.FieldOrderID, paymentauditlog.FieldAction, paymentauditlog.FieldDetail, paymentauditlog.FieldOperator: + values[i] = new(sql.NullString) + case paymentauditlog.FieldCreatedAt: + values[i] = new(sql.NullTime) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the PaymentAuditLog fields. +func (_m *PaymentAuditLog) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case paymentauditlog.FieldID: + value, ok := values[i].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + _m.ID = int64(value.Int64) + case paymentauditlog.FieldOrderID: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field order_id", values[i]) + } else if value.Valid { + _m.OrderID = value.String + } + case paymentauditlog.FieldAction: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field action", values[i]) + } else if value.Valid { + _m.Action = value.String + } + case paymentauditlog.FieldDetail: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field detail", values[i]) + } else if value.Valid { + _m.Detail = value.String + } + case paymentauditlog.FieldOperator: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field operator", values[i]) + } else if value.Valid { + _m.Operator = value.String + } + case paymentauditlog.FieldCreatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field created_at", values[i]) + } else if value.Valid { + _m.CreatedAt = value.Time + } + default: + _m.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the PaymentAuditLog. +// This includes values selected through modifiers, order, etc. +func (_m *PaymentAuditLog) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + +// Update returns a builder for updating this PaymentAuditLog. +// Note that you need to call PaymentAuditLog.Unwrap() before calling this method if this PaymentAuditLog +// was returned from a transaction, and the transaction was committed or rolled back. +func (_m *PaymentAuditLog) Update() *PaymentAuditLogUpdateOne { + return NewPaymentAuditLogClient(_m.config).UpdateOne(_m) +} + +// Unwrap unwraps the PaymentAuditLog entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (_m *PaymentAuditLog) Unwrap() *PaymentAuditLog { + _tx, ok := _m.config.driver.(*txDriver) + if !ok { + panic("ent: PaymentAuditLog is not a transactional entity") + } + _m.config.driver = _tx.drv + return _m +} + +// String implements the fmt.Stringer. +func (_m *PaymentAuditLog) String() string { + var builder strings.Builder + builder.WriteString("PaymentAuditLog(") + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) + builder.WriteString("order_id=") + builder.WriteString(_m.OrderID) + builder.WriteString(", ") + builder.WriteString("action=") + builder.WriteString(_m.Action) + builder.WriteString(", ") + builder.WriteString("detail=") + builder.WriteString(_m.Detail) + builder.WriteString(", ") + builder.WriteString("operator=") + builder.WriteString(_m.Operator) + builder.WriteString(", ") + builder.WriteString("created_at=") + builder.WriteString(_m.CreatedAt.Format(time.ANSIC)) + builder.WriteByte(')') + return builder.String() +} + +// PaymentAuditLogs is a parsable slice of PaymentAuditLog. +type PaymentAuditLogs []*PaymentAuditLog diff --git a/backend/ent/paymentauditlog/paymentauditlog.go b/backend/ent/paymentauditlog/paymentauditlog.go new file mode 100644 index 0000000000..9d480eef21 --- /dev/null +++ b/backend/ent/paymentauditlog/paymentauditlog.go @@ -0,0 +1,96 @@ +// Code generated by ent, DO NOT EDIT. + +package paymentauditlog + +import ( + "time" + + "entgo.io/ent/dialect/sql" +) + +const ( + // Label holds the string label denoting the paymentauditlog type in the database. + Label = "payment_audit_log" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldOrderID holds the string denoting the order_id field in the database. + FieldOrderID = "order_id" + // FieldAction holds the string denoting the action field in the database. + FieldAction = "action" + // FieldDetail holds the string denoting the detail field in the database. + FieldDetail = "detail" + // FieldOperator holds the string denoting the operator field in the database. + FieldOperator = "operator" + // FieldCreatedAt holds the string denoting the created_at field in the database. + FieldCreatedAt = "created_at" + // Table holds the table name of the paymentauditlog in the database. + Table = "payment_audit_logs" +) + +// Columns holds all SQL columns for paymentauditlog fields. +var Columns = []string{ + FieldID, + FieldOrderID, + FieldAction, + FieldDetail, + FieldOperator, + FieldCreatedAt, +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + return false +} + +var ( + // OrderIDValidator is a validator for the "order_id" field. It is called by the builders before save. + OrderIDValidator func(string) error + // ActionValidator is a validator for the "action" field. It is called by the builders before save. + ActionValidator func(string) error + // DefaultDetail holds the default value on creation for the "detail" field. + DefaultDetail string + // DefaultOperator holds the default value on creation for the "operator" field. + DefaultOperator string + // OperatorValidator is a validator for the "operator" field. It is called by the builders before save. + OperatorValidator func(string) error + // DefaultCreatedAt holds the default value on creation for the "created_at" field. + DefaultCreatedAt func() time.Time +) + +// OrderOption defines the ordering options for the PaymentAuditLog queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByOrderID orders the results by the order_id field. +func ByOrderID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldOrderID, opts...).ToFunc() +} + +// ByAction orders the results by the action field. +func ByAction(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldAction, opts...).ToFunc() +} + +// ByDetail orders the results by the detail field. +func ByDetail(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldDetail, opts...).ToFunc() +} + +// ByOperator orders the results by the operator field. +func ByOperator(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldOperator, opts...).ToFunc() +} + +// ByCreatedAt orders the results by the created_at field. +func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() +} diff --git a/backend/ent/paymentauditlog/where.go b/backend/ent/paymentauditlog/where.go new file mode 100644 index 0000000000..2fd80a4213 --- /dev/null +++ b/backend/ent/paymentauditlog/where.go @@ -0,0 +1,395 @@ +// Code generated by ent, DO NOT EDIT. + +package paymentauditlog + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "github.com/Wei-Shaw/sub2api/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id int64) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int64) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int64) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int64) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int64) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int64) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int64) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int64) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int64) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldLTE(FieldID, id)) +} + +// OrderID applies equality check predicate on the "order_id" field. It's identical to OrderIDEQ. +func OrderID(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldEQ(FieldOrderID, v)) +} + +// Action applies equality check predicate on the "action" field. It's identical to ActionEQ. +func Action(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldEQ(FieldAction, v)) +} + +// Detail applies equality check predicate on the "detail" field. It's identical to DetailEQ. +func Detail(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldEQ(FieldDetail, v)) +} + +// Operator applies equality check predicate on the "operator" field. It's identical to OperatorEQ. +func Operator(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldEQ(FieldOperator, v)) +} + +// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. +func CreatedAt(v time.Time) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldEQ(FieldCreatedAt, v)) +} + +// OrderIDEQ applies the EQ predicate on the "order_id" field. +func OrderIDEQ(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldEQ(FieldOrderID, v)) +} + +// OrderIDNEQ applies the NEQ predicate on the "order_id" field. +func OrderIDNEQ(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldNEQ(FieldOrderID, v)) +} + +// OrderIDIn applies the In predicate on the "order_id" field. +func OrderIDIn(vs ...string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldIn(FieldOrderID, vs...)) +} + +// OrderIDNotIn applies the NotIn predicate on the "order_id" field. +func OrderIDNotIn(vs ...string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldNotIn(FieldOrderID, vs...)) +} + +// OrderIDGT applies the GT predicate on the "order_id" field. +func OrderIDGT(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldGT(FieldOrderID, v)) +} + +// OrderIDGTE applies the GTE predicate on the "order_id" field. +func OrderIDGTE(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldGTE(FieldOrderID, v)) +} + +// OrderIDLT applies the LT predicate on the "order_id" field. +func OrderIDLT(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldLT(FieldOrderID, v)) +} + +// OrderIDLTE applies the LTE predicate on the "order_id" field. +func OrderIDLTE(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldLTE(FieldOrderID, v)) +} + +// OrderIDContains applies the Contains predicate on the "order_id" field. +func OrderIDContains(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldContains(FieldOrderID, v)) +} + +// OrderIDHasPrefix applies the HasPrefix predicate on the "order_id" field. +func OrderIDHasPrefix(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldHasPrefix(FieldOrderID, v)) +} + +// OrderIDHasSuffix applies the HasSuffix predicate on the "order_id" field. +func OrderIDHasSuffix(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldHasSuffix(FieldOrderID, v)) +} + +// OrderIDEqualFold applies the EqualFold predicate on the "order_id" field. +func OrderIDEqualFold(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldEqualFold(FieldOrderID, v)) +} + +// OrderIDContainsFold applies the ContainsFold predicate on the "order_id" field. +func OrderIDContainsFold(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldContainsFold(FieldOrderID, v)) +} + +// ActionEQ applies the EQ predicate on the "action" field. +func ActionEQ(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldEQ(FieldAction, v)) +} + +// ActionNEQ applies the NEQ predicate on the "action" field. +func ActionNEQ(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldNEQ(FieldAction, v)) +} + +// ActionIn applies the In predicate on the "action" field. +func ActionIn(vs ...string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldIn(FieldAction, vs...)) +} + +// ActionNotIn applies the NotIn predicate on the "action" field. +func ActionNotIn(vs ...string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldNotIn(FieldAction, vs...)) +} + +// ActionGT applies the GT predicate on the "action" field. +func ActionGT(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldGT(FieldAction, v)) +} + +// ActionGTE applies the GTE predicate on the "action" field. +func ActionGTE(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldGTE(FieldAction, v)) +} + +// ActionLT applies the LT predicate on the "action" field. +func ActionLT(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldLT(FieldAction, v)) +} + +// ActionLTE applies the LTE predicate on the "action" field. +func ActionLTE(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldLTE(FieldAction, v)) +} + +// ActionContains applies the Contains predicate on the "action" field. +func ActionContains(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldContains(FieldAction, v)) +} + +// ActionHasPrefix applies the HasPrefix predicate on the "action" field. +func ActionHasPrefix(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldHasPrefix(FieldAction, v)) +} + +// ActionHasSuffix applies the HasSuffix predicate on the "action" field. +func ActionHasSuffix(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldHasSuffix(FieldAction, v)) +} + +// ActionEqualFold applies the EqualFold predicate on the "action" field. +func ActionEqualFold(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldEqualFold(FieldAction, v)) +} + +// ActionContainsFold applies the ContainsFold predicate on the "action" field. +func ActionContainsFold(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldContainsFold(FieldAction, v)) +} + +// DetailEQ applies the EQ predicate on the "detail" field. +func DetailEQ(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldEQ(FieldDetail, v)) +} + +// DetailNEQ applies the NEQ predicate on the "detail" field. +func DetailNEQ(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldNEQ(FieldDetail, v)) +} + +// DetailIn applies the In predicate on the "detail" field. +func DetailIn(vs ...string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldIn(FieldDetail, vs...)) +} + +// DetailNotIn applies the NotIn predicate on the "detail" field. +func DetailNotIn(vs ...string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldNotIn(FieldDetail, vs...)) +} + +// DetailGT applies the GT predicate on the "detail" field. +func DetailGT(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldGT(FieldDetail, v)) +} + +// DetailGTE applies the GTE predicate on the "detail" field. +func DetailGTE(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldGTE(FieldDetail, v)) +} + +// DetailLT applies the LT predicate on the "detail" field. +func DetailLT(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldLT(FieldDetail, v)) +} + +// DetailLTE applies the LTE predicate on the "detail" field. +func DetailLTE(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldLTE(FieldDetail, v)) +} + +// DetailContains applies the Contains predicate on the "detail" field. +func DetailContains(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldContains(FieldDetail, v)) +} + +// DetailHasPrefix applies the HasPrefix predicate on the "detail" field. +func DetailHasPrefix(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldHasPrefix(FieldDetail, v)) +} + +// DetailHasSuffix applies the HasSuffix predicate on the "detail" field. +func DetailHasSuffix(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldHasSuffix(FieldDetail, v)) +} + +// DetailEqualFold applies the EqualFold predicate on the "detail" field. +func DetailEqualFold(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldEqualFold(FieldDetail, v)) +} + +// DetailContainsFold applies the ContainsFold predicate on the "detail" field. +func DetailContainsFold(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldContainsFold(FieldDetail, v)) +} + +// OperatorEQ applies the EQ predicate on the "operator" field. +func OperatorEQ(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldEQ(FieldOperator, v)) +} + +// OperatorNEQ applies the NEQ predicate on the "operator" field. +func OperatorNEQ(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldNEQ(FieldOperator, v)) +} + +// OperatorIn applies the In predicate on the "operator" field. +func OperatorIn(vs ...string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldIn(FieldOperator, vs...)) +} + +// OperatorNotIn applies the NotIn predicate on the "operator" field. +func OperatorNotIn(vs ...string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldNotIn(FieldOperator, vs...)) +} + +// OperatorGT applies the GT predicate on the "operator" field. +func OperatorGT(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldGT(FieldOperator, v)) +} + +// OperatorGTE applies the GTE predicate on the "operator" field. +func OperatorGTE(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldGTE(FieldOperator, v)) +} + +// OperatorLT applies the LT predicate on the "operator" field. +func OperatorLT(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldLT(FieldOperator, v)) +} + +// OperatorLTE applies the LTE predicate on the "operator" field. +func OperatorLTE(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldLTE(FieldOperator, v)) +} + +// OperatorContains applies the Contains predicate on the "operator" field. +func OperatorContains(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldContains(FieldOperator, v)) +} + +// OperatorHasPrefix applies the HasPrefix predicate on the "operator" field. +func OperatorHasPrefix(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldHasPrefix(FieldOperator, v)) +} + +// OperatorHasSuffix applies the HasSuffix predicate on the "operator" field. +func OperatorHasSuffix(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldHasSuffix(FieldOperator, v)) +} + +// OperatorEqualFold applies the EqualFold predicate on the "operator" field. +func OperatorEqualFold(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldEqualFold(FieldOperator, v)) +} + +// OperatorContainsFold applies the ContainsFold predicate on the "operator" field. +func OperatorContainsFold(v string) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldContainsFold(FieldOperator, v)) +} + +// CreatedAtEQ applies the EQ predicate on the "created_at" field. +func CreatedAtEQ(v time.Time) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldEQ(FieldCreatedAt, v)) +} + +// CreatedAtNEQ applies the NEQ predicate on the "created_at" field. +func CreatedAtNEQ(v time.Time) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldNEQ(FieldCreatedAt, v)) +} + +// CreatedAtIn applies the In predicate on the "created_at" field. +func CreatedAtIn(vs ...time.Time) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldIn(FieldCreatedAt, vs...)) +} + +// CreatedAtNotIn applies the NotIn predicate on the "created_at" field. +func CreatedAtNotIn(vs ...time.Time) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldNotIn(FieldCreatedAt, vs...)) +} + +// CreatedAtGT applies the GT predicate on the "created_at" field. +func CreatedAtGT(v time.Time) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldGT(FieldCreatedAt, v)) +} + +// CreatedAtGTE applies the GTE predicate on the "created_at" field. +func CreatedAtGTE(v time.Time) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldGTE(FieldCreatedAt, v)) +} + +// CreatedAtLT applies the LT predicate on the "created_at" field. +func CreatedAtLT(v time.Time) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldLT(FieldCreatedAt, v)) +} + +// CreatedAtLTE applies the LTE predicate on the "created_at" field. +func CreatedAtLTE(v time.Time) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.FieldLTE(FieldCreatedAt, v)) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.PaymentAuditLog) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.PaymentAuditLog) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.PaymentAuditLog) predicate.PaymentAuditLog { + return predicate.PaymentAuditLog(sql.NotPredicates(p)) +} diff --git a/backend/ent/paymentauditlog_create.go b/backend/ent/paymentauditlog_create.go new file mode 100644 index 0000000000..1906aba110 --- /dev/null +++ b/backend/ent/paymentauditlog_create.go @@ -0,0 +1,696 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/paymentauditlog" +) + +// PaymentAuditLogCreate is the builder for creating a PaymentAuditLog entity. +type PaymentAuditLogCreate struct { + config + mutation *PaymentAuditLogMutation + hooks []Hook + conflict []sql.ConflictOption +} + +// SetOrderID sets the "order_id" field. +func (_c *PaymentAuditLogCreate) SetOrderID(v string) *PaymentAuditLogCreate { + _c.mutation.SetOrderID(v) + return _c +} + +// SetAction sets the "action" field. +func (_c *PaymentAuditLogCreate) SetAction(v string) *PaymentAuditLogCreate { + _c.mutation.SetAction(v) + return _c +} + +// SetDetail sets the "detail" field. +func (_c *PaymentAuditLogCreate) SetDetail(v string) *PaymentAuditLogCreate { + _c.mutation.SetDetail(v) + return _c +} + +// SetNillableDetail sets the "detail" field if the given value is not nil. +func (_c *PaymentAuditLogCreate) SetNillableDetail(v *string) *PaymentAuditLogCreate { + if v != nil { + _c.SetDetail(*v) + } + return _c +} + +// SetOperator sets the "operator" field. +func (_c *PaymentAuditLogCreate) SetOperator(v string) *PaymentAuditLogCreate { + _c.mutation.SetOperator(v) + return _c +} + +// SetNillableOperator sets the "operator" field if the given value is not nil. +func (_c *PaymentAuditLogCreate) SetNillableOperator(v *string) *PaymentAuditLogCreate { + if v != nil { + _c.SetOperator(*v) + } + return _c +} + +// SetCreatedAt sets the "created_at" field. +func (_c *PaymentAuditLogCreate) SetCreatedAt(v time.Time) *PaymentAuditLogCreate { + _c.mutation.SetCreatedAt(v) + return _c +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (_c *PaymentAuditLogCreate) SetNillableCreatedAt(v *time.Time) *PaymentAuditLogCreate { + if v != nil { + _c.SetCreatedAt(*v) + } + return _c +} + +// Mutation returns the PaymentAuditLogMutation object of the builder. +func (_c *PaymentAuditLogCreate) Mutation() *PaymentAuditLogMutation { + return _c.mutation +} + +// Save creates the PaymentAuditLog in the database. +func (_c *PaymentAuditLogCreate) Save(ctx context.Context) (*PaymentAuditLog, error) { + _c.defaults() + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (_c *PaymentAuditLogCreate) SaveX(ctx context.Context) *PaymentAuditLog { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *PaymentAuditLogCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *PaymentAuditLogCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_c *PaymentAuditLogCreate) defaults() { + if _, ok := _c.mutation.Detail(); !ok { + v := paymentauditlog.DefaultDetail + _c.mutation.SetDetail(v) + } + if _, ok := _c.mutation.Operator(); !ok { + v := paymentauditlog.DefaultOperator + _c.mutation.SetOperator(v) + } + if _, ok := _c.mutation.CreatedAt(); !ok { + v := paymentauditlog.DefaultCreatedAt() + _c.mutation.SetCreatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_c *PaymentAuditLogCreate) check() error { + if _, ok := _c.mutation.OrderID(); !ok { + return &ValidationError{Name: "order_id", err: errors.New(`ent: missing required field "PaymentAuditLog.order_id"`)} + } + if v, ok := _c.mutation.OrderID(); ok { + if err := paymentauditlog.OrderIDValidator(v); err != nil { + return &ValidationError{Name: "order_id", err: fmt.Errorf(`ent: validator failed for field "PaymentAuditLog.order_id": %w`, err)} + } + } + if _, ok := _c.mutation.Action(); !ok { + return &ValidationError{Name: "action", err: errors.New(`ent: missing required field "PaymentAuditLog.action"`)} + } + if v, ok := _c.mutation.Action(); ok { + if err := paymentauditlog.ActionValidator(v); err != nil { + return &ValidationError{Name: "action", err: fmt.Errorf(`ent: validator failed for field "PaymentAuditLog.action": %w`, err)} + } + } + if _, ok := _c.mutation.Detail(); !ok { + return &ValidationError{Name: "detail", err: errors.New(`ent: missing required field "PaymentAuditLog.detail"`)} + } + if _, ok := _c.mutation.Operator(); !ok { + return &ValidationError{Name: "operator", err: errors.New(`ent: missing required field "PaymentAuditLog.operator"`)} + } + if v, ok := _c.mutation.Operator(); ok { + if err := paymentauditlog.OperatorValidator(v); err != nil { + return &ValidationError{Name: "operator", err: fmt.Errorf(`ent: validator failed for field "PaymentAuditLog.operator": %w`, err)} + } + } + if _, ok := _c.mutation.CreatedAt(); !ok { + return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "PaymentAuditLog.created_at"`)} + } + return nil +} + +func (_c *PaymentAuditLogCreate) sqlSave(ctx context.Context) (*PaymentAuditLog, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + id := _spec.ID.Value.(int64) + _node.ID = int64(id) + _c.mutation.id = &_node.ID + _c.mutation.done = true + return _node, nil +} + +func (_c *PaymentAuditLogCreate) createSpec() (*PaymentAuditLog, *sqlgraph.CreateSpec) { + var ( + _node = &PaymentAuditLog{config: _c.config} + _spec = sqlgraph.NewCreateSpec(paymentauditlog.Table, sqlgraph.NewFieldSpec(paymentauditlog.FieldID, field.TypeInt64)) + ) + _spec.OnConflict = _c.conflict + if value, ok := _c.mutation.OrderID(); ok { + _spec.SetField(paymentauditlog.FieldOrderID, field.TypeString, value) + _node.OrderID = value + } + if value, ok := _c.mutation.Action(); ok { + _spec.SetField(paymentauditlog.FieldAction, field.TypeString, value) + _node.Action = value + } + if value, ok := _c.mutation.Detail(); ok { + _spec.SetField(paymentauditlog.FieldDetail, field.TypeString, value) + _node.Detail = value + } + if value, ok := _c.mutation.Operator(); ok { + _spec.SetField(paymentauditlog.FieldOperator, field.TypeString, value) + _node.Operator = value + } + if value, ok := _c.mutation.CreatedAt(); ok { + _spec.SetField(paymentauditlog.FieldCreatedAt, field.TypeTime, value) + _node.CreatedAt = value + } + return _node, _spec +} + +// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause +// of the `INSERT` statement. For example: +// +// client.PaymentAuditLog.Create(). +// SetOrderID(v). +// OnConflict( +// // Update the row with the new values +// // the was proposed for insertion. +// sql.ResolveWithNewValues(), +// ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.PaymentAuditLogUpsert) { +// SetOrderID(v+v). +// }). +// Exec(ctx) +func (_c *PaymentAuditLogCreate) OnConflict(opts ...sql.ConflictOption) *PaymentAuditLogUpsertOne { + _c.conflict = opts + return &PaymentAuditLogUpsertOne{ + create: _c, + } +} + +// OnConflictColumns calls `OnConflict` and configures the columns +// as conflict target. Using this option is equivalent to using: +// +// client.PaymentAuditLog.Create(). +// OnConflict(sql.ConflictColumns(columns...)). +// Exec(ctx) +func (_c *PaymentAuditLogCreate) OnConflictColumns(columns ...string) *PaymentAuditLogUpsertOne { + _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) + return &PaymentAuditLogUpsertOne{ + create: _c, + } +} + +type ( + // PaymentAuditLogUpsertOne is the builder for "upsert"-ing + // one PaymentAuditLog node. + PaymentAuditLogUpsertOne struct { + create *PaymentAuditLogCreate + } + + // PaymentAuditLogUpsert is the "OnConflict" setter. + PaymentAuditLogUpsert struct { + *sql.UpdateSet + } +) + +// SetOrderID sets the "order_id" field. +func (u *PaymentAuditLogUpsert) SetOrderID(v string) *PaymentAuditLogUpsert { + u.Set(paymentauditlog.FieldOrderID, v) + return u +} + +// UpdateOrderID sets the "order_id" field to the value that was provided on create. +func (u *PaymentAuditLogUpsert) UpdateOrderID() *PaymentAuditLogUpsert { + u.SetExcluded(paymentauditlog.FieldOrderID) + return u +} + +// SetAction sets the "action" field. +func (u *PaymentAuditLogUpsert) SetAction(v string) *PaymentAuditLogUpsert { + u.Set(paymentauditlog.FieldAction, v) + return u +} + +// UpdateAction sets the "action" field to the value that was provided on create. +func (u *PaymentAuditLogUpsert) UpdateAction() *PaymentAuditLogUpsert { + u.SetExcluded(paymentauditlog.FieldAction) + return u +} + +// SetDetail sets the "detail" field. +func (u *PaymentAuditLogUpsert) SetDetail(v string) *PaymentAuditLogUpsert { + u.Set(paymentauditlog.FieldDetail, v) + return u +} + +// UpdateDetail sets the "detail" field to the value that was provided on create. +func (u *PaymentAuditLogUpsert) UpdateDetail() *PaymentAuditLogUpsert { + u.SetExcluded(paymentauditlog.FieldDetail) + return u +} + +// SetOperator sets the "operator" field. +func (u *PaymentAuditLogUpsert) SetOperator(v string) *PaymentAuditLogUpsert { + u.Set(paymentauditlog.FieldOperator, v) + return u +} + +// UpdateOperator sets the "operator" field to the value that was provided on create. +func (u *PaymentAuditLogUpsert) UpdateOperator() *PaymentAuditLogUpsert { + u.SetExcluded(paymentauditlog.FieldOperator) + return u +} + +// UpdateNewValues updates the mutable fields using the new values that were set on create. +// Using this option is equivalent to using: +// +// client.PaymentAuditLog.Create(). +// OnConflict( +// sql.ResolveWithNewValues(), +// ). +// Exec(ctx) +func (u *PaymentAuditLogUpsertOne) UpdateNewValues() *PaymentAuditLogUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { + if _, exists := u.create.mutation.CreatedAt(); exists { + s.SetIgnore(paymentauditlog.FieldCreatedAt) + } + })) + return u +} + +// Ignore sets each column to itself in case of conflict. +// Using this option is equivalent to using: +// +// client.PaymentAuditLog.Create(). +// OnConflict(sql.ResolveWithIgnore()). +// Exec(ctx) +func (u *PaymentAuditLogUpsertOne) Ignore() *PaymentAuditLogUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) + return u +} + +// DoNothing configures the conflict_action to `DO NOTHING`. +// Supported only by SQLite and PostgreSQL. +func (u *PaymentAuditLogUpsertOne) DoNothing() *PaymentAuditLogUpsertOne { + u.create.conflict = append(u.create.conflict, sql.DoNothing()) + return u +} + +// Update allows overriding fields `UPDATE` values. See the PaymentAuditLogCreate.OnConflict +// documentation for more info. +func (u *PaymentAuditLogUpsertOne) Update(set func(*PaymentAuditLogUpsert)) *PaymentAuditLogUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { + set(&PaymentAuditLogUpsert{UpdateSet: update}) + })) + return u +} + +// SetOrderID sets the "order_id" field. +func (u *PaymentAuditLogUpsertOne) SetOrderID(v string) *PaymentAuditLogUpsertOne { + return u.Update(func(s *PaymentAuditLogUpsert) { + s.SetOrderID(v) + }) +} + +// UpdateOrderID sets the "order_id" field to the value that was provided on create. +func (u *PaymentAuditLogUpsertOne) UpdateOrderID() *PaymentAuditLogUpsertOne { + return u.Update(func(s *PaymentAuditLogUpsert) { + s.UpdateOrderID() + }) +} + +// SetAction sets the "action" field. +func (u *PaymentAuditLogUpsertOne) SetAction(v string) *PaymentAuditLogUpsertOne { + return u.Update(func(s *PaymentAuditLogUpsert) { + s.SetAction(v) + }) +} + +// UpdateAction sets the "action" field to the value that was provided on create. +func (u *PaymentAuditLogUpsertOne) UpdateAction() *PaymentAuditLogUpsertOne { + return u.Update(func(s *PaymentAuditLogUpsert) { + s.UpdateAction() + }) +} + +// SetDetail sets the "detail" field. +func (u *PaymentAuditLogUpsertOne) SetDetail(v string) *PaymentAuditLogUpsertOne { + return u.Update(func(s *PaymentAuditLogUpsert) { + s.SetDetail(v) + }) +} + +// UpdateDetail sets the "detail" field to the value that was provided on create. +func (u *PaymentAuditLogUpsertOne) UpdateDetail() *PaymentAuditLogUpsertOne { + return u.Update(func(s *PaymentAuditLogUpsert) { + s.UpdateDetail() + }) +} + +// SetOperator sets the "operator" field. +func (u *PaymentAuditLogUpsertOne) SetOperator(v string) *PaymentAuditLogUpsertOne { + return u.Update(func(s *PaymentAuditLogUpsert) { + s.SetOperator(v) + }) +} + +// UpdateOperator sets the "operator" field to the value that was provided on create. +func (u *PaymentAuditLogUpsertOne) UpdateOperator() *PaymentAuditLogUpsertOne { + return u.Update(func(s *PaymentAuditLogUpsert) { + s.UpdateOperator() + }) +} + +// Exec executes the query. +func (u *PaymentAuditLogUpsertOne) Exec(ctx context.Context) error { + if len(u.create.conflict) == 0 { + return errors.New("ent: missing options for PaymentAuditLogCreate.OnConflict") + } + return u.create.Exec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (u *PaymentAuditLogUpsertOne) ExecX(ctx context.Context) { + if err := u.create.Exec(ctx); err != nil { + panic(err) + } +} + +// Exec executes the UPSERT query and returns the inserted/updated ID. +func (u *PaymentAuditLogUpsertOne) ID(ctx context.Context) (id int64, err error) { + node, err := u.create.Save(ctx) + if err != nil { + return id, err + } + return node.ID, nil +} + +// IDX is like ID, but panics if an error occurs. +func (u *PaymentAuditLogUpsertOne) IDX(ctx context.Context) int64 { + id, err := u.ID(ctx) + if err != nil { + panic(err) + } + return id +} + +// PaymentAuditLogCreateBulk is the builder for creating many PaymentAuditLog entities in bulk. +type PaymentAuditLogCreateBulk struct { + config + err error + builders []*PaymentAuditLogCreate + conflict []sql.ConflictOption +} + +// Save creates the PaymentAuditLog entities in the database. +func (_c *PaymentAuditLogCreateBulk) Save(ctx context.Context) ([]*PaymentAuditLog, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*PaymentAuditLog, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { + func(i int, root context.Context) { + builder := _c.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PaymentAuditLogMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.OnConflict = _c.conflict + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + if specs[i].ID.Value != nil { + id := specs[i].ID.Value.(int64) + nodes[i].ID = int64(id) + } + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (_c *PaymentAuditLogCreateBulk) SaveX(ctx context.Context) []*PaymentAuditLog { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *PaymentAuditLogCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *PaymentAuditLogCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause +// of the `INSERT` statement. For example: +// +// client.PaymentAuditLog.CreateBulk(builders...). +// OnConflict( +// // Update the row with the new values +// // the was proposed for insertion. +// sql.ResolveWithNewValues(), +// ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.PaymentAuditLogUpsert) { +// SetOrderID(v+v). +// }). +// Exec(ctx) +func (_c *PaymentAuditLogCreateBulk) OnConflict(opts ...sql.ConflictOption) *PaymentAuditLogUpsertBulk { + _c.conflict = opts + return &PaymentAuditLogUpsertBulk{ + create: _c, + } +} + +// OnConflictColumns calls `OnConflict` and configures the columns +// as conflict target. Using this option is equivalent to using: +// +// client.PaymentAuditLog.Create(). +// OnConflict(sql.ConflictColumns(columns...)). +// Exec(ctx) +func (_c *PaymentAuditLogCreateBulk) OnConflictColumns(columns ...string) *PaymentAuditLogUpsertBulk { + _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) + return &PaymentAuditLogUpsertBulk{ + create: _c, + } +} + +// PaymentAuditLogUpsertBulk is the builder for "upsert"-ing +// a bulk of PaymentAuditLog nodes. +type PaymentAuditLogUpsertBulk struct { + create *PaymentAuditLogCreateBulk +} + +// UpdateNewValues updates the mutable fields using the new values that +// were set on create. Using this option is equivalent to using: +// +// client.PaymentAuditLog.Create(). +// OnConflict( +// sql.ResolveWithNewValues(), +// ). +// Exec(ctx) +func (u *PaymentAuditLogUpsertBulk) UpdateNewValues() *PaymentAuditLogUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { + for _, b := range u.create.builders { + if _, exists := b.mutation.CreatedAt(); exists { + s.SetIgnore(paymentauditlog.FieldCreatedAt) + } + } + })) + return u +} + +// Ignore sets each column to itself in case of conflict. +// Using this option is equivalent to using: +// +// client.PaymentAuditLog.Create(). +// OnConflict(sql.ResolveWithIgnore()). +// Exec(ctx) +func (u *PaymentAuditLogUpsertBulk) Ignore() *PaymentAuditLogUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) + return u +} + +// DoNothing configures the conflict_action to `DO NOTHING`. +// Supported only by SQLite and PostgreSQL. +func (u *PaymentAuditLogUpsertBulk) DoNothing() *PaymentAuditLogUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.DoNothing()) + return u +} + +// Update allows overriding fields `UPDATE` values. See the PaymentAuditLogCreateBulk.OnConflict +// documentation for more info. +func (u *PaymentAuditLogUpsertBulk) Update(set func(*PaymentAuditLogUpsert)) *PaymentAuditLogUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { + set(&PaymentAuditLogUpsert{UpdateSet: update}) + })) + return u +} + +// SetOrderID sets the "order_id" field. +func (u *PaymentAuditLogUpsertBulk) SetOrderID(v string) *PaymentAuditLogUpsertBulk { + return u.Update(func(s *PaymentAuditLogUpsert) { + s.SetOrderID(v) + }) +} + +// UpdateOrderID sets the "order_id" field to the value that was provided on create. +func (u *PaymentAuditLogUpsertBulk) UpdateOrderID() *PaymentAuditLogUpsertBulk { + return u.Update(func(s *PaymentAuditLogUpsert) { + s.UpdateOrderID() + }) +} + +// SetAction sets the "action" field. +func (u *PaymentAuditLogUpsertBulk) SetAction(v string) *PaymentAuditLogUpsertBulk { + return u.Update(func(s *PaymentAuditLogUpsert) { + s.SetAction(v) + }) +} + +// UpdateAction sets the "action" field to the value that was provided on create. +func (u *PaymentAuditLogUpsertBulk) UpdateAction() *PaymentAuditLogUpsertBulk { + return u.Update(func(s *PaymentAuditLogUpsert) { + s.UpdateAction() + }) +} + +// SetDetail sets the "detail" field. +func (u *PaymentAuditLogUpsertBulk) SetDetail(v string) *PaymentAuditLogUpsertBulk { + return u.Update(func(s *PaymentAuditLogUpsert) { + s.SetDetail(v) + }) +} + +// UpdateDetail sets the "detail" field to the value that was provided on create. +func (u *PaymentAuditLogUpsertBulk) UpdateDetail() *PaymentAuditLogUpsertBulk { + return u.Update(func(s *PaymentAuditLogUpsert) { + s.UpdateDetail() + }) +} + +// SetOperator sets the "operator" field. +func (u *PaymentAuditLogUpsertBulk) SetOperator(v string) *PaymentAuditLogUpsertBulk { + return u.Update(func(s *PaymentAuditLogUpsert) { + s.SetOperator(v) + }) +} + +// UpdateOperator sets the "operator" field to the value that was provided on create. +func (u *PaymentAuditLogUpsertBulk) UpdateOperator() *PaymentAuditLogUpsertBulk { + return u.Update(func(s *PaymentAuditLogUpsert) { + s.UpdateOperator() + }) +} + +// Exec executes the query. +func (u *PaymentAuditLogUpsertBulk) Exec(ctx context.Context) error { + if u.create.err != nil { + return u.create.err + } + for i, b := range u.create.builders { + if len(b.conflict) != 0 { + return fmt.Errorf("ent: OnConflict was set for builder %d. Set it on the PaymentAuditLogCreateBulk instead", i) + } + } + if len(u.create.conflict) == 0 { + return errors.New("ent: missing options for PaymentAuditLogCreateBulk.OnConflict") + } + return u.create.Exec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (u *PaymentAuditLogUpsertBulk) ExecX(ctx context.Context) { + if err := u.create.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/backend/ent/paymentauditlog_delete.go b/backend/ent/paymentauditlog_delete.go new file mode 100644 index 0000000000..ca22d8db37 --- /dev/null +++ b/backend/ent/paymentauditlog_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/paymentauditlog" + "github.com/Wei-Shaw/sub2api/ent/predicate" +) + +// PaymentAuditLogDelete is the builder for deleting a PaymentAuditLog entity. +type PaymentAuditLogDelete struct { + config + hooks []Hook + mutation *PaymentAuditLogMutation +} + +// Where appends a list predicates to the PaymentAuditLogDelete builder. +func (_d *PaymentAuditLogDelete) Where(ps ...predicate.PaymentAuditLog) *PaymentAuditLogDelete { + _d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (_d *PaymentAuditLogDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *PaymentAuditLogDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (_d *PaymentAuditLogDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(paymentauditlog.Table, sqlgraph.NewFieldSpec(paymentauditlog.FieldID, field.TypeInt64)) + if ps := _d.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + _d.mutation.done = true + return affected, err +} + +// PaymentAuditLogDeleteOne is the builder for deleting a single PaymentAuditLog entity. +type PaymentAuditLogDeleteOne struct { + _d *PaymentAuditLogDelete +} + +// Where appends a list predicates to the PaymentAuditLogDelete builder. +func (_d *PaymentAuditLogDeleteOne) Where(ps ...predicate.PaymentAuditLog) *PaymentAuditLogDeleteOne { + _d._d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query. +func (_d *PaymentAuditLogDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{paymentauditlog.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *PaymentAuditLogDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/backend/ent/paymentauditlog_query.go b/backend/ent/paymentauditlog_query.go new file mode 100644 index 0000000000..7a4e9115e7 --- /dev/null +++ b/backend/ent/paymentauditlog_query.go @@ -0,0 +1,564 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "math" + + "entgo.io/ent" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/paymentauditlog" + "github.com/Wei-Shaw/sub2api/ent/predicate" +) + +// PaymentAuditLogQuery is the builder for querying PaymentAuditLog entities. +type PaymentAuditLogQuery struct { + config + ctx *QueryContext + order []paymentauditlog.OrderOption + inters []Interceptor + predicates []predicate.PaymentAuditLog + modifiers []func(*sql.Selector) + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the PaymentAuditLogQuery builder. +func (_q *PaymentAuditLogQuery) Where(ps ...predicate.PaymentAuditLog) *PaymentAuditLogQuery { + _q.predicates = append(_q.predicates, ps...) + return _q +} + +// Limit the number of records to be returned by this query. +func (_q *PaymentAuditLogQuery) Limit(limit int) *PaymentAuditLogQuery { + _q.ctx.Limit = &limit + return _q +} + +// Offset to start from. +func (_q *PaymentAuditLogQuery) Offset(offset int) *PaymentAuditLogQuery { + _q.ctx.Offset = &offset + return _q +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (_q *PaymentAuditLogQuery) Unique(unique bool) *PaymentAuditLogQuery { + _q.ctx.Unique = &unique + return _q +} + +// Order specifies how the records should be ordered. +func (_q *PaymentAuditLogQuery) Order(o ...paymentauditlog.OrderOption) *PaymentAuditLogQuery { + _q.order = append(_q.order, o...) + return _q +} + +// First returns the first PaymentAuditLog entity from the query. +// Returns a *NotFoundError when no PaymentAuditLog was found. +func (_q *PaymentAuditLogQuery) First(ctx context.Context) (*PaymentAuditLog, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{paymentauditlog.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (_q *PaymentAuditLogQuery) FirstX(ctx context.Context) *PaymentAuditLog { + node, err := _q.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first PaymentAuditLog ID from the query. +// Returns a *NotFoundError when no PaymentAuditLog ID was found. +func (_q *PaymentAuditLogQuery) FirstID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{paymentauditlog.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (_q *PaymentAuditLogQuery) FirstIDX(ctx context.Context) int64 { + id, err := _q.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single PaymentAuditLog entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one PaymentAuditLog entity is found. +// Returns a *NotFoundError when no PaymentAuditLog entities are found. +func (_q *PaymentAuditLogQuery) Only(ctx context.Context) (*PaymentAuditLog, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{paymentauditlog.Label} + default: + return nil, &NotSingularError{paymentauditlog.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (_q *PaymentAuditLogQuery) OnlyX(ctx context.Context) *PaymentAuditLog { + node, err := _q.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only PaymentAuditLog ID in the query. +// Returns a *NotSingularError when more than one PaymentAuditLog ID is found. +// Returns a *NotFoundError when no entities are found. +func (_q *PaymentAuditLogQuery) OnlyID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{paymentauditlog.Label} + default: + err = &NotSingularError{paymentauditlog.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (_q *PaymentAuditLogQuery) OnlyIDX(ctx context.Context) int64 { + id, err := _q.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of PaymentAuditLogs. +func (_q *PaymentAuditLogQuery) All(ctx context.Context) ([]*PaymentAuditLog, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*PaymentAuditLog, *PaymentAuditLogQuery]() + return withInterceptors[[]*PaymentAuditLog](ctx, _q, qr, _q.inters) +} + +// AllX is like All, but panics if an error occurs. +func (_q *PaymentAuditLogQuery) AllX(ctx context.Context) []*PaymentAuditLog { + nodes, err := _q.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of PaymentAuditLog IDs. +func (_q *PaymentAuditLogQuery) IDs(ctx context.Context) (ids []int64, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(paymentauditlog.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (_q *PaymentAuditLogQuery) IDsX(ctx context.Context) []int64 { + ids, err := _q.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (_q *PaymentAuditLogQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, _q, querierCount[*PaymentAuditLogQuery](), _q.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (_q *PaymentAuditLogQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (_q *PaymentAuditLogQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (_q *PaymentAuditLogQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the PaymentAuditLogQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (_q *PaymentAuditLogQuery) Clone() *PaymentAuditLogQuery { + if _q == nil { + return nil + } + return &PaymentAuditLogQuery{ + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]paymentauditlog.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.PaymentAuditLog{}, _q.predicates...), + // clone intermediate query. + sql: _q.sql.Clone(), + path: _q.path, + } +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// OrderID string `json:"order_id,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.PaymentAuditLog.Query(). +// GroupBy(paymentauditlog.FieldOrderID). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (_q *PaymentAuditLogQuery) GroupBy(field string, fields ...string) *PaymentAuditLogGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &PaymentAuditLogGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields + grbuild.label = paymentauditlog.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// OrderID string `json:"order_id,omitempty"` +// } +// +// client.PaymentAuditLog.Query(). +// Select(paymentauditlog.FieldOrderID). +// Scan(ctx, &v) +func (_q *PaymentAuditLogQuery) Select(fields ...string) *PaymentAuditLogSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &PaymentAuditLogSelect{PaymentAuditLogQuery: _q} + sbuild.label = paymentauditlog.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a PaymentAuditLogSelect configured with the given aggregations. +func (_q *PaymentAuditLogQuery) Aggregate(fns ...AggregateFunc) *PaymentAuditLogSelect { + return _q.Select().Aggregate(fns...) +} + +func (_q *PaymentAuditLogQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { + if !paymentauditlog.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if _q.path != nil { + prev, err := _q.path(ctx) + if err != nil { + return err + } + _q.sql = prev + } + return nil +} + +func (_q *PaymentAuditLogQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*PaymentAuditLog, error) { + var ( + nodes = []*PaymentAuditLog{} + _spec = _q.querySpec() + ) + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*PaymentAuditLog).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &PaymentAuditLog{config: _q.config} + nodes = append(nodes, node) + return node.assignValues(columns, values) + } + if len(_q.modifiers) > 0 { + _spec.Modifiers = _q.modifiers + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + return nodes, nil +} + +func (_q *PaymentAuditLogQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + if len(_q.modifiers) > 0 { + _spec.Modifiers = _q.modifiers + } + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique + } + return sqlgraph.CountNodes(ctx, _q.driver, _spec) +} + +func (_q *PaymentAuditLogQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(paymentauditlog.Table, paymentauditlog.Columns, sqlgraph.NewFieldSpec(paymentauditlog.FieldID, field.TypeInt64)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true + } + if fields := _q.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, paymentauditlog.FieldID) + for i := range fields { + if fields[i] != paymentauditlog.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := _q.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := _q.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := _q.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := _q.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (_q *PaymentAuditLogQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) + t1 := builder.Table(paymentauditlog.Table) + columns := _q.ctx.Fields + if len(columns) == 0 { + columns = paymentauditlog.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if _q.sql != nil { + selector = _q.sql + selector.Select(selector.Columns(columns...)...) + } + if _q.ctx.Unique != nil && *_q.ctx.Unique { + selector.Distinct() + } + for _, m := range _q.modifiers { + m(selector) + } + for _, p := range _q.predicates { + p(selector) + } + for _, p := range _q.order { + p(selector) + } + if offset := _q.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := _q.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// ForUpdate locks the selected rows against concurrent updates, and prevent them from being +// updated, deleted or "selected ... for update" by other sessions, until the transaction is +// either committed or rolled-back. +func (_q *PaymentAuditLogQuery) ForUpdate(opts ...sql.LockOption) *PaymentAuditLogQuery { + if _q.driver.Dialect() == dialect.Postgres { + _q.Unique(false) + } + _q.modifiers = append(_q.modifiers, func(s *sql.Selector) { + s.ForUpdate(opts...) + }) + return _q +} + +// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock +// on any rows that are read. Other sessions can read the rows, but cannot modify them +// until your transaction commits. +func (_q *PaymentAuditLogQuery) ForShare(opts ...sql.LockOption) *PaymentAuditLogQuery { + if _q.driver.Dialect() == dialect.Postgres { + _q.Unique(false) + } + _q.modifiers = append(_q.modifiers, func(s *sql.Selector) { + s.ForShare(opts...) + }) + return _q +} + +// PaymentAuditLogGroupBy is the group-by builder for PaymentAuditLog entities. +type PaymentAuditLogGroupBy struct { + selector + build *PaymentAuditLogQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (_g *PaymentAuditLogGroupBy) Aggregate(fns ...AggregateFunc) *PaymentAuditLogGroupBy { + _g.fns = append(_g.fns, fns...) + return _g +} + +// Scan applies the selector query and scans the result into the given value. +func (_g *PaymentAuditLogGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*PaymentAuditLogQuery, *PaymentAuditLogGroupBy](ctx, _g.build, _g, _g.build.inters, v) +} + +func (_g *PaymentAuditLogGroupBy) sqlScan(ctx context.Context, root *PaymentAuditLogQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*_g.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// PaymentAuditLogSelect is the builder for selecting fields of PaymentAuditLog entities. +type PaymentAuditLogSelect struct { + *PaymentAuditLogQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *PaymentAuditLogSelect) Aggregate(fns ...AggregateFunc) *PaymentAuditLogSelect { + _s.fns = append(_s.fns, fns...) + return _s +} + +// Scan applies the selector query and scans the result into the given value. +func (_s *PaymentAuditLogSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*PaymentAuditLogQuery, *PaymentAuditLogSelect](ctx, _s.PaymentAuditLogQuery, _s, _s.inters, v) +} + +func (_s *PaymentAuditLogSelect) sqlScan(ctx context.Context, root *PaymentAuditLogQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/backend/ent/paymentauditlog_update.go b/backend/ent/paymentauditlog_update.go new file mode 100644 index 0000000000..52b4afe794 --- /dev/null +++ b/backend/ent/paymentauditlog_update.go @@ -0,0 +1,357 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/paymentauditlog" + "github.com/Wei-Shaw/sub2api/ent/predicate" +) + +// PaymentAuditLogUpdate is the builder for updating PaymentAuditLog entities. +type PaymentAuditLogUpdate struct { + config + hooks []Hook + mutation *PaymentAuditLogMutation +} + +// Where appends a list predicates to the PaymentAuditLogUpdate builder. +func (_u *PaymentAuditLogUpdate) Where(ps ...predicate.PaymentAuditLog) *PaymentAuditLogUpdate { + _u.mutation.Where(ps...) + return _u +} + +// SetOrderID sets the "order_id" field. +func (_u *PaymentAuditLogUpdate) SetOrderID(v string) *PaymentAuditLogUpdate { + _u.mutation.SetOrderID(v) + return _u +} + +// SetNillableOrderID sets the "order_id" field if the given value is not nil. +func (_u *PaymentAuditLogUpdate) SetNillableOrderID(v *string) *PaymentAuditLogUpdate { + if v != nil { + _u.SetOrderID(*v) + } + return _u +} + +// SetAction sets the "action" field. +func (_u *PaymentAuditLogUpdate) SetAction(v string) *PaymentAuditLogUpdate { + _u.mutation.SetAction(v) + return _u +} + +// SetNillableAction sets the "action" field if the given value is not nil. +func (_u *PaymentAuditLogUpdate) SetNillableAction(v *string) *PaymentAuditLogUpdate { + if v != nil { + _u.SetAction(*v) + } + return _u +} + +// SetDetail sets the "detail" field. +func (_u *PaymentAuditLogUpdate) SetDetail(v string) *PaymentAuditLogUpdate { + _u.mutation.SetDetail(v) + return _u +} + +// SetNillableDetail sets the "detail" field if the given value is not nil. +func (_u *PaymentAuditLogUpdate) SetNillableDetail(v *string) *PaymentAuditLogUpdate { + if v != nil { + _u.SetDetail(*v) + } + return _u +} + +// SetOperator sets the "operator" field. +func (_u *PaymentAuditLogUpdate) SetOperator(v string) *PaymentAuditLogUpdate { + _u.mutation.SetOperator(v) + return _u +} + +// SetNillableOperator sets the "operator" field if the given value is not nil. +func (_u *PaymentAuditLogUpdate) SetNillableOperator(v *string) *PaymentAuditLogUpdate { + if v != nil { + _u.SetOperator(*v) + } + return _u +} + +// Mutation returns the PaymentAuditLogMutation object of the builder. +func (_u *PaymentAuditLogUpdate) Mutation() *PaymentAuditLogMutation { + return _u.mutation +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (_u *PaymentAuditLogUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *PaymentAuditLogUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (_u *PaymentAuditLogUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *PaymentAuditLogUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *PaymentAuditLogUpdate) check() error { + if v, ok := _u.mutation.OrderID(); ok { + if err := paymentauditlog.OrderIDValidator(v); err != nil { + return &ValidationError{Name: "order_id", err: fmt.Errorf(`ent: validator failed for field "PaymentAuditLog.order_id": %w`, err)} + } + } + if v, ok := _u.mutation.Action(); ok { + if err := paymentauditlog.ActionValidator(v); err != nil { + return &ValidationError{Name: "action", err: fmt.Errorf(`ent: validator failed for field "PaymentAuditLog.action": %w`, err)} + } + } + if v, ok := _u.mutation.Operator(); ok { + if err := paymentauditlog.OperatorValidator(v); err != nil { + return &ValidationError{Name: "operator", err: fmt.Errorf(`ent: validator failed for field "PaymentAuditLog.operator": %w`, err)} + } + } + return nil +} + +func (_u *PaymentAuditLogUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(paymentauditlog.Table, paymentauditlog.Columns, sqlgraph.NewFieldSpec(paymentauditlog.FieldID, field.TypeInt64)) + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.OrderID(); ok { + _spec.SetField(paymentauditlog.FieldOrderID, field.TypeString, value) + } + if value, ok := _u.mutation.Action(); ok { + _spec.SetField(paymentauditlog.FieldAction, field.TypeString, value) + } + if value, ok := _u.mutation.Detail(); ok { + _spec.SetField(paymentauditlog.FieldDetail, field.TypeString, value) + } + if value, ok := _u.mutation.Operator(); ok { + _spec.SetField(paymentauditlog.FieldOperator, field.TypeString, value) + } + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{paymentauditlog.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + _u.mutation.done = true + return _node, nil +} + +// PaymentAuditLogUpdateOne is the builder for updating a single PaymentAuditLog entity. +type PaymentAuditLogUpdateOne struct { + config + fields []string + hooks []Hook + mutation *PaymentAuditLogMutation +} + +// SetOrderID sets the "order_id" field. +func (_u *PaymentAuditLogUpdateOne) SetOrderID(v string) *PaymentAuditLogUpdateOne { + _u.mutation.SetOrderID(v) + return _u +} + +// SetNillableOrderID sets the "order_id" field if the given value is not nil. +func (_u *PaymentAuditLogUpdateOne) SetNillableOrderID(v *string) *PaymentAuditLogUpdateOne { + if v != nil { + _u.SetOrderID(*v) + } + return _u +} + +// SetAction sets the "action" field. +func (_u *PaymentAuditLogUpdateOne) SetAction(v string) *PaymentAuditLogUpdateOne { + _u.mutation.SetAction(v) + return _u +} + +// SetNillableAction sets the "action" field if the given value is not nil. +func (_u *PaymentAuditLogUpdateOne) SetNillableAction(v *string) *PaymentAuditLogUpdateOne { + if v != nil { + _u.SetAction(*v) + } + return _u +} + +// SetDetail sets the "detail" field. +func (_u *PaymentAuditLogUpdateOne) SetDetail(v string) *PaymentAuditLogUpdateOne { + _u.mutation.SetDetail(v) + return _u +} + +// SetNillableDetail sets the "detail" field if the given value is not nil. +func (_u *PaymentAuditLogUpdateOne) SetNillableDetail(v *string) *PaymentAuditLogUpdateOne { + if v != nil { + _u.SetDetail(*v) + } + return _u +} + +// SetOperator sets the "operator" field. +func (_u *PaymentAuditLogUpdateOne) SetOperator(v string) *PaymentAuditLogUpdateOne { + _u.mutation.SetOperator(v) + return _u +} + +// SetNillableOperator sets the "operator" field if the given value is not nil. +func (_u *PaymentAuditLogUpdateOne) SetNillableOperator(v *string) *PaymentAuditLogUpdateOne { + if v != nil { + _u.SetOperator(*v) + } + return _u +} + +// Mutation returns the PaymentAuditLogMutation object of the builder. +func (_u *PaymentAuditLogUpdateOne) Mutation() *PaymentAuditLogMutation { + return _u.mutation +} + +// Where appends a list predicates to the PaymentAuditLogUpdate builder. +func (_u *PaymentAuditLogUpdateOne) Where(ps ...predicate.PaymentAuditLog) *PaymentAuditLogUpdateOne { + _u.mutation.Where(ps...) + return _u +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (_u *PaymentAuditLogUpdateOne) Select(field string, fields ...string) *PaymentAuditLogUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u +} + +// Save executes the query and returns the updated PaymentAuditLog entity. +func (_u *PaymentAuditLogUpdateOne) Save(ctx context.Context) (*PaymentAuditLog, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *PaymentAuditLogUpdateOne) SaveX(ctx context.Context) *PaymentAuditLog { + node, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (_u *PaymentAuditLogUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *PaymentAuditLogUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *PaymentAuditLogUpdateOne) check() error { + if v, ok := _u.mutation.OrderID(); ok { + if err := paymentauditlog.OrderIDValidator(v); err != nil { + return &ValidationError{Name: "order_id", err: fmt.Errorf(`ent: validator failed for field "PaymentAuditLog.order_id": %w`, err)} + } + } + if v, ok := _u.mutation.Action(); ok { + if err := paymentauditlog.ActionValidator(v); err != nil { + return &ValidationError{Name: "action", err: fmt.Errorf(`ent: validator failed for field "PaymentAuditLog.action": %w`, err)} + } + } + if v, ok := _u.mutation.Operator(); ok { + if err := paymentauditlog.OperatorValidator(v); err != nil { + return &ValidationError{Name: "operator", err: fmt.Errorf(`ent: validator failed for field "PaymentAuditLog.operator": %w`, err)} + } + } + return nil +} + +func (_u *PaymentAuditLogUpdateOne) sqlSave(ctx context.Context) (_node *PaymentAuditLog, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(paymentauditlog.Table, paymentauditlog.Columns, sqlgraph.NewFieldSpec(paymentauditlog.FieldID, field.TypeInt64)) + id, ok := _u.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "PaymentAuditLog.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := _u.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, paymentauditlog.FieldID) + for _, f := range fields { + if !paymentauditlog.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != paymentauditlog.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.OrderID(); ok { + _spec.SetField(paymentauditlog.FieldOrderID, field.TypeString, value) + } + if value, ok := _u.mutation.Action(); ok { + _spec.SetField(paymentauditlog.FieldAction, field.TypeString, value) + } + if value, ok := _u.mutation.Detail(); ok { + _spec.SetField(paymentauditlog.FieldDetail, field.TypeString, value) + } + if value, ok := _u.mutation.Operator(); ok { + _spec.SetField(paymentauditlog.FieldOperator, field.TypeString, value) + } + _node = &PaymentAuditLog{config: _u.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{paymentauditlog.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + _u.mutation.done = true + return _node, nil +} diff --git a/backend/ent/paymentorder.go b/backend/ent/paymentorder.go new file mode 100644 index 0000000000..99838a3f55 --- /dev/null +++ b/backend/ent/paymentorder.go @@ -0,0 +1,578 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "github.com/Wei-Shaw/sub2api/ent/paymentorder" + "github.com/Wei-Shaw/sub2api/ent/user" +) + +// PaymentOrder is the model entity for the PaymentOrder schema. +type PaymentOrder struct { + config `json:"-"` + // ID of the ent. + ID int64 `json:"id,omitempty"` + // UserID holds the value of the "user_id" field. + UserID int64 `json:"user_id,omitempty"` + // UserEmail holds the value of the "user_email" field. + UserEmail string `json:"user_email,omitempty"` + // UserName holds the value of the "user_name" field. + UserName string `json:"user_name,omitempty"` + // UserNotes holds the value of the "user_notes" field. + UserNotes *string `json:"user_notes,omitempty"` + // Amount holds the value of the "amount" field. + Amount float64 `json:"amount,omitempty"` + // PayAmount holds the value of the "pay_amount" field. + PayAmount float64 `json:"pay_amount,omitempty"` + // FeeRate holds the value of the "fee_rate" field. + FeeRate float64 `json:"fee_rate,omitempty"` + // RechargeCode holds the value of the "recharge_code" field. + RechargeCode string `json:"recharge_code,omitempty"` + // PaymentType holds the value of the "payment_type" field. + PaymentType string `json:"payment_type,omitempty"` + // PaymentTradeNo holds the value of the "payment_trade_no" field. + PaymentTradeNo string `json:"payment_trade_no,omitempty"` + // PayURL holds the value of the "pay_url" field. + PayURL *string `json:"pay_url,omitempty"` + // QrCode holds the value of the "qr_code" field. + QrCode *string `json:"qr_code,omitempty"` + // QrCodeImg holds the value of the "qr_code_img" field. + QrCodeImg *string `json:"qr_code_img,omitempty"` + // OrderType holds the value of the "order_type" field. + OrderType string `json:"order_type,omitempty"` + // PlanID holds the value of the "plan_id" field. + PlanID *int64 `json:"plan_id,omitempty"` + // SubscriptionGroupID holds the value of the "subscription_group_id" field. + SubscriptionGroupID *int64 `json:"subscription_group_id,omitempty"` + // SubscriptionDays holds the value of the "subscription_days" field. + SubscriptionDays *int `json:"subscription_days,omitempty"` + // ProviderInstanceID holds the value of the "provider_instance_id" field. + ProviderInstanceID *string `json:"provider_instance_id,omitempty"` + // Status holds the value of the "status" field. + Status string `json:"status,omitempty"` + // RefundAmount holds the value of the "refund_amount" field. + RefundAmount float64 `json:"refund_amount,omitempty"` + // RefundReason holds the value of the "refund_reason" field. + RefundReason *string `json:"refund_reason,omitempty"` + // RefundAt holds the value of the "refund_at" field. + RefundAt *time.Time `json:"refund_at,omitempty"` + // ForceRefund holds the value of the "force_refund" field. + ForceRefund bool `json:"force_refund,omitempty"` + // RefundRequestedAt holds the value of the "refund_requested_at" field. + RefundRequestedAt *time.Time `json:"refund_requested_at,omitempty"` + // RefundRequestReason holds the value of the "refund_request_reason" field. + RefundRequestReason *string `json:"refund_request_reason,omitempty"` + // RefundRequestedBy holds the value of the "refund_requested_by" field. + RefundRequestedBy *string `json:"refund_requested_by,omitempty"` + // ExpiresAt holds the value of the "expires_at" field. + ExpiresAt time.Time `json:"expires_at,omitempty"` + // PaidAt holds the value of the "paid_at" field. + PaidAt *time.Time `json:"paid_at,omitempty"` + // CompletedAt holds the value of the "completed_at" field. + CompletedAt *time.Time `json:"completed_at,omitempty"` + // FailedAt holds the value of the "failed_at" field. + FailedAt *time.Time `json:"failed_at,omitempty"` + // FailedReason holds the value of the "failed_reason" field. + FailedReason *string `json:"failed_reason,omitempty"` + // ClientIP holds the value of the "client_ip" field. + ClientIP string `json:"client_ip,omitempty"` + // SrcHost holds the value of the "src_host" field. + SrcHost string `json:"src_host,omitempty"` + // SrcURL holds the value of the "src_url" field. + SrcURL *string `json:"src_url,omitempty"` + // CreatedAt holds the value of the "created_at" field. + CreatedAt time.Time `json:"created_at,omitempty"` + // UpdatedAt holds the value of the "updated_at" field. + UpdatedAt time.Time `json:"updated_at,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the PaymentOrderQuery when eager-loading is set. + Edges PaymentOrderEdges `json:"edges"` + selectValues sql.SelectValues +} + +// PaymentOrderEdges holds the relations/edges for other nodes in the graph. +type PaymentOrderEdges struct { + // User holds the value of the user edge. + User *User `json:"user,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [1]bool +} + +// UserOrErr returns the User value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e PaymentOrderEdges) UserOrErr() (*User, error) { + if e.User != nil { + return e.User, nil + } else if e.loadedTypes[0] { + return nil, &NotFoundError{label: user.Label} + } + return nil, &NotLoadedError{edge: "user"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*PaymentOrder) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case paymentorder.FieldForceRefund: + values[i] = new(sql.NullBool) + case paymentorder.FieldAmount, paymentorder.FieldPayAmount, paymentorder.FieldFeeRate, paymentorder.FieldRefundAmount: + values[i] = new(sql.NullFloat64) + case paymentorder.FieldID, paymentorder.FieldUserID, paymentorder.FieldPlanID, paymentorder.FieldSubscriptionGroupID, paymentorder.FieldSubscriptionDays: + values[i] = new(sql.NullInt64) + case paymentorder.FieldUserEmail, paymentorder.FieldUserName, paymentorder.FieldUserNotes, paymentorder.FieldRechargeCode, paymentorder.FieldPaymentType, paymentorder.FieldPaymentTradeNo, paymentorder.FieldPayURL, paymentorder.FieldQrCode, paymentorder.FieldQrCodeImg, paymentorder.FieldOrderType, paymentorder.FieldProviderInstanceID, paymentorder.FieldStatus, paymentorder.FieldRefundReason, paymentorder.FieldRefundRequestReason, paymentorder.FieldRefundRequestedBy, paymentorder.FieldFailedReason, paymentorder.FieldClientIP, paymentorder.FieldSrcHost, paymentorder.FieldSrcURL: + values[i] = new(sql.NullString) + case paymentorder.FieldRefundAt, paymentorder.FieldRefundRequestedAt, paymentorder.FieldExpiresAt, paymentorder.FieldPaidAt, paymentorder.FieldCompletedAt, paymentorder.FieldFailedAt, paymentorder.FieldCreatedAt, paymentorder.FieldUpdatedAt: + values[i] = new(sql.NullTime) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the PaymentOrder fields. +func (_m *PaymentOrder) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case paymentorder.FieldID: + value, ok := values[i].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + _m.ID = int64(value.Int64) + case paymentorder.FieldUserID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field user_id", values[i]) + } else if value.Valid { + _m.UserID = value.Int64 + } + case paymentorder.FieldUserEmail: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field user_email", values[i]) + } else if value.Valid { + _m.UserEmail = value.String + } + case paymentorder.FieldUserName: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field user_name", values[i]) + } else if value.Valid { + _m.UserName = value.String + } + case paymentorder.FieldUserNotes: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field user_notes", values[i]) + } else if value.Valid { + _m.UserNotes = new(string) + *_m.UserNotes = value.String + } + case paymentorder.FieldAmount: + if value, ok := values[i].(*sql.NullFloat64); !ok { + return fmt.Errorf("unexpected type %T for field amount", values[i]) + } else if value.Valid { + _m.Amount = value.Float64 + } + case paymentorder.FieldPayAmount: + if value, ok := values[i].(*sql.NullFloat64); !ok { + return fmt.Errorf("unexpected type %T for field pay_amount", values[i]) + } else if value.Valid { + _m.PayAmount = value.Float64 + } + case paymentorder.FieldFeeRate: + if value, ok := values[i].(*sql.NullFloat64); !ok { + return fmt.Errorf("unexpected type %T for field fee_rate", values[i]) + } else if value.Valid { + _m.FeeRate = value.Float64 + } + case paymentorder.FieldRechargeCode: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field recharge_code", values[i]) + } else if value.Valid { + _m.RechargeCode = value.String + } + case paymentorder.FieldPaymentType: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field payment_type", values[i]) + } else if value.Valid { + _m.PaymentType = value.String + } + case paymentorder.FieldPaymentTradeNo: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field payment_trade_no", values[i]) + } else if value.Valid { + _m.PaymentTradeNo = value.String + } + case paymentorder.FieldPayURL: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field pay_url", values[i]) + } else if value.Valid { + _m.PayURL = new(string) + *_m.PayURL = value.String + } + case paymentorder.FieldQrCode: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field qr_code", values[i]) + } else if value.Valid { + _m.QrCode = new(string) + *_m.QrCode = value.String + } + case paymentorder.FieldQrCodeImg: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field qr_code_img", values[i]) + } else if value.Valid { + _m.QrCodeImg = new(string) + *_m.QrCodeImg = value.String + } + case paymentorder.FieldOrderType: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field order_type", values[i]) + } else if value.Valid { + _m.OrderType = value.String + } + case paymentorder.FieldPlanID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field plan_id", values[i]) + } else if value.Valid { + _m.PlanID = new(int64) + *_m.PlanID = value.Int64 + } + case paymentorder.FieldSubscriptionGroupID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field subscription_group_id", values[i]) + } else if value.Valid { + _m.SubscriptionGroupID = new(int64) + *_m.SubscriptionGroupID = value.Int64 + } + case paymentorder.FieldSubscriptionDays: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field subscription_days", values[i]) + } else if value.Valid { + _m.SubscriptionDays = new(int) + *_m.SubscriptionDays = int(value.Int64) + } + case paymentorder.FieldProviderInstanceID: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field provider_instance_id", values[i]) + } else if value.Valid { + _m.ProviderInstanceID = new(string) + *_m.ProviderInstanceID = value.String + } + case paymentorder.FieldStatus: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field status", values[i]) + } else if value.Valid { + _m.Status = value.String + } + case paymentorder.FieldRefundAmount: + if value, ok := values[i].(*sql.NullFloat64); !ok { + return fmt.Errorf("unexpected type %T for field refund_amount", values[i]) + } else if value.Valid { + _m.RefundAmount = value.Float64 + } + case paymentorder.FieldRefundReason: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field refund_reason", values[i]) + } else if value.Valid { + _m.RefundReason = new(string) + *_m.RefundReason = value.String + } + case paymentorder.FieldRefundAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field refund_at", values[i]) + } else if value.Valid { + _m.RefundAt = new(time.Time) + *_m.RefundAt = value.Time + } + case paymentorder.FieldForceRefund: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field force_refund", values[i]) + } else if value.Valid { + _m.ForceRefund = value.Bool + } + case paymentorder.FieldRefundRequestedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field refund_requested_at", values[i]) + } else if value.Valid { + _m.RefundRequestedAt = new(time.Time) + *_m.RefundRequestedAt = value.Time + } + case paymentorder.FieldRefundRequestReason: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field refund_request_reason", values[i]) + } else if value.Valid { + _m.RefundRequestReason = new(string) + *_m.RefundRequestReason = value.String + } + case paymentorder.FieldRefundRequestedBy: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field refund_requested_by", values[i]) + } else if value.Valid { + _m.RefundRequestedBy = new(string) + *_m.RefundRequestedBy = value.String + } + case paymentorder.FieldExpiresAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field expires_at", values[i]) + } else if value.Valid { + _m.ExpiresAt = value.Time + } + case paymentorder.FieldPaidAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field paid_at", values[i]) + } else if value.Valid { + _m.PaidAt = new(time.Time) + *_m.PaidAt = value.Time + } + case paymentorder.FieldCompletedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field completed_at", values[i]) + } else if value.Valid { + _m.CompletedAt = new(time.Time) + *_m.CompletedAt = value.Time + } + case paymentorder.FieldFailedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field failed_at", values[i]) + } else if value.Valid { + _m.FailedAt = new(time.Time) + *_m.FailedAt = value.Time + } + case paymentorder.FieldFailedReason: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field failed_reason", values[i]) + } else if value.Valid { + _m.FailedReason = new(string) + *_m.FailedReason = value.String + } + case paymentorder.FieldClientIP: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field client_ip", values[i]) + } else if value.Valid { + _m.ClientIP = value.String + } + case paymentorder.FieldSrcHost: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field src_host", values[i]) + } else if value.Valid { + _m.SrcHost = value.String + } + case paymentorder.FieldSrcURL: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field src_url", values[i]) + } else if value.Valid { + _m.SrcURL = new(string) + *_m.SrcURL = value.String + } + case paymentorder.FieldCreatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field created_at", values[i]) + } else if value.Valid { + _m.CreatedAt = value.Time + } + case paymentorder.FieldUpdatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field updated_at", values[i]) + } else if value.Valid { + _m.UpdatedAt = value.Time + } + default: + _m.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the PaymentOrder. +// This includes values selected through modifiers, order, etc. +func (_m *PaymentOrder) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + +// QueryUser queries the "user" edge of the PaymentOrder entity. +func (_m *PaymentOrder) QueryUser() *UserQuery { + return NewPaymentOrderClient(_m.config).QueryUser(_m) +} + +// Update returns a builder for updating this PaymentOrder. +// Note that you need to call PaymentOrder.Unwrap() before calling this method if this PaymentOrder +// was returned from a transaction, and the transaction was committed or rolled back. +func (_m *PaymentOrder) Update() *PaymentOrderUpdateOne { + return NewPaymentOrderClient(_m.config).UpdateOne(_m) +} + +// Unwrap unwraps the PaymentOrder entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (_m *PaymentOrder) Unwrap() *PaymentOrder { + _tx, ok := _m.config.driver.(*txDriver) + if !ok { + panic("ent: PaymentOrder is not a transactional entity") + } + _m.config.driver = _tx.drv + return _m +} + +// String implements the fmt.Stringer. +func (_m *PaymentOrder) String() string { + var builder strings.Builder + builder.WriteString("PaymentOrder(") + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) + builder.WriteString("user_id=") + builder.WriteString(fmt.Sprintf("%v", _m.UserID)) + builder.WriteString(", ") + builder.WriteString("user_email=") + builder.WriteString(_m.UserEmail) + builder.WriteString(", ") + builder.WriteString("user_name=") + builder.WriteString(_m.UserName) + builder.WriteString(", ") + if v := _m.UserNotes; v != nil { + builder.WriteString("user_notes=") + builder.WriteString(*v) + } + builder.WriteString(", ") + builder.WriteString("amount=") + builder.WriteString(fmt.Sprintf("%v", _m.Amount)) + builder.WriteString(", ") + builder.WriteString("pay_amount=") + builder.WriteString(fmt.Sprintf("%v", _m.PayAmount)) + builder.WriteString(", ") + builder.WriteString("fee_rate=") + builder.WriteString(fmt.Sprintf("%v", _m.FeeRate)) + builder.WriteString(", ") + builder.WriteString("recharge_code=") + builder.WriteString(_m.RechargeCode) + builder.WriteString(", ") + builder.WriteString("payment_type=") + builder.WriteString(_m.PaymentType) + builder.WriteString(", ") + builder.WriteString("payment_trade_no=") + builder.WriteString(_m.PaymentTradeNo) + builder.WriteString(", ") + if v := _m.PayURL; v != nil { + builder.WriteString("pay_url=") + builder.WriteString(*v) + } + builder.WriteString(", ") + if v := _m.QrCode; v != nil { + builder.WriteString("qr_code=") + builder.WriteString(*v) + } + builder.WriteString(", ") + if v := _m.QrCodeImg; v != nil { + builder.WriteString("qr_code_img=") + builder.WriteString(*v) + } + builder.WriteString(", ") + builder.WriteString("order_type=") + builder.WriteString(_m.OrderType) + builder.WriteString(", ") + if v := _m.PlanID; v != nil { + builder.WriteString("plan_id=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") + if v := _m.SubscriptionGroupID; v != nil { + builder.WriteString("subscription_group_id=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") + if v := _m.SubscriptionDays; v != nil { + builder.WriteString("subscription_days=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") + if v := _m.ProviderInstanceID; v != nil { + builder.WriteString("provider_instance_id=") + builder.WriteString(*v) + } + builder.WriteString(", ") + builder.WriteString("status=") + builder.WriteString(_m.Status) + builder.WriteString(", ") + builder.WriteString("refund_amount=") + builder.WriteString(fmt.Sprintf("%v", _m.RefundAmount)) + builder.WriteString(", ") + if v := _m.RefundReason; v != nil { + builder.WriteString("refund_reason=") + builder.WriteString(*v) + } + builder.WriteString(", ") + if v := _m.RefundAt; v != nil { + builder.WriteString("refund_at=") + builder.WriteString(v.Format(time.ANSIC)) + } + builder.WriteString(", ") + builder.WriteString("force_refund=") + builder.WriteString(fmt.Sprintf("%v", _m.ForceRefund)) + builder.WriteString(", ") + if v := _m.RefundRequestedAt; v != nil { + builder.WriteString("refund_requested_at=") + builder.WriteString(v.Format(time.ANSIC)) + } + builder.WriteString(", ") + if v := _m.RefundRequestReason; v != nil { + builder.WriteString("refund_request_reason=") + builder.WriteString(*v) + } + builder.WriteString(", ") + if v := _m.RefundRequestedBy; v != nil { + builder.WriteString("refund_requested_by=") + builder.WriteString(*v) + } + builder.WriteString(", ") + builder.WriteString("expires_at=") + builder.WriteString(_m.ExpiresAt.Format(time.ANSIC)) + builder.WriteString(", ") + if v := _m.PaidAt; v != nil { + builder.WriteString("paid_at=") + builder.WriteString(v.Format(time.ANSIC)) + } + builder.WriteString(", ") + if v := _m.CompletedAt; v != nil { + builder.WriteString("completed_at=") + builder.WriteString(v.Format(time.ANSIC)) + } + builder.WriteString(", ") + if v := _m.FailedAt; v != nil { + builder.WriteString("failed_at=") + builder.WriteString(v.Format(time.ANSIC)) + } + builder.WriteString(", ") + if v := _m.FailedReason; v != nil { + builder.WriteString("failed_reason=") + builder.WriteString(*v) + } + builder.WriteString(", ") + builder.WriteString("client_ip=") + builder.WriteString(_m.ClientIP) + builder.WriteString(", ") + builder.WriteString("src_host=") + builder.WriteString(_m.SrcHost) + builder.WriteString(", ") + if v := _m.SrcURL; v != nil { + builder.WriteString("src_url=") + builder.WriteString(*v) + } + builder.WriteString(", ") + builder.WriteString("created_at=") + builder.WriteString(_m.CreatedAt.Format(time.ANSIC)) + builder.WriteString(", ") + builder.WriteString("updated_at=") + builder.WriteString(_m.UpdatedAt.Format(time.ANSIC)) + builder.WriteByte(')') + return builder.String() +} + +// PaymentOrders is a parsable slice of PaymentOrder. +type PaymentOrders []*PaymentOrder diff --git a/backend/ent/paymentorder/paymentorder.go b/backend/ent/paymentorder/paymentorder.go new file mode 100644 index 0000000000..860da5a512 --- /dev/null +++ b/backend/ent/paymentorder/paymentorder.go @@ -0,0 +1,394 @@ +// Code generated by ent, DO NOT EDIT. + +package paymentorder + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" +) + +const ( + // Label holds the string label denoting the paymentorder type in the database. + Label = "payment_order" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldUserID holds the string denoting the user_id field in the database. + FieldUserID = "user_id" + // FieldUserEmail holds the string denoting the user_email field in the database. + FieldUserEmail = "user_email" + // FieldUserName holds the string denoting the user_name field in the database. + FieldUserName = "user_name" + // FieldUserNotes holds the string denoting the user_notes field in the database. + FieldUserNotes = "user_notes" + // FieldAmount holds the string denoting the amount field in the database. + FieldAmount = "amount" + // FieldPayAmount holds the string denoting the pay_amount field in the database. + FieldPayAmount = "pay_amount" + // FieldFeeRate holds the string denoting the fee_rate field in the database. + FieldFeeRate = "fee_rate" + // FieldRechargeCode holds the string denoting the recharge_code field in the database. + FieldRechargeCode = "recharge_code" + // FieldPaymentType holds the string denoting the payment_type field in the database. + FieldPaymentType = "payment_type" + // FieldPaymentTradeNo holds the string denoting the payment_trade_no field in the database. + FieldPaymentTradeNo = "payment_trade_no" + // FieldPayURL holds the string denoting the pay_url field in the database. + FieldPayURL = "pay_url" + // FieldQrCode holds the string denoting the qr_code field in the database. + FieldQrCode = "qr_code" + // FieldQrCodeImg holds the string denoting the qr_code_img field in the database. + FieldQrCodeImg = "qr_code_img" + // FieldOrderType holds the string denoting the order_type field in the database. + FieldOrderType = "order_type" + // FieldPlanID holds the string denoting the plan_id field in the database. + FieldPlanID = "plan_id" + // FieldSubscriptionGroupID holds the string denoting the subscription_group_id field in the database. + FieldSubscriptionGroupID = "subscription_group_id" + // FieldSubscriptionDays holds the string denoting the subscription_days field in the database. + FieldSubscriptionDays = "subscription_days" + // FieldProviderInstanceID holds the string denoting the provider_instance_id field in the database. + FieldProviderInstanceID = "provider_instance_id" + // FieldStatus holds the string denoting the status field in the database. + FieldStatus = "status" + // FieldRefundAmount holds the string denoting the refund_amount field in the database. + FieldRefundAmount = "refund_amount" + // FieldRefundReason holds the string denoting the refund_reason field in the database. + FieldRefundReason = "refund_reason" + // FieldRefundAt holds the string denoting the refund_at field in the database. + FieldRefundAt = "refund_at" + // FieldForceRefund holds the string denoting the force_refund field in the database. + FieldForceRefund = "force_refund" + // FieldRefundRequestedAt holds the string denoting the refund_requested_at field in the database. + FieldRefundRequestedAt = "refund_requested_at" + // FieldRefundRequestReason holds the string denoting the refund_request_reason field in the database. + FieldRefundRequestReason = "refund_request_reason" + // FieldRefundRequestedBy holds the string denoting the refund_requested_by field in the database. + FieldRefundRequestedBy = "refund_requested_by" + // FieldExpiresAt holds the string denoting the expires_at field in the database. + FieldExpiresAt = "expires_at" + // FieldPaidAt holds the string denoting the paid_at field in the database. + FieldPaidAt = "paid_at" + // FieldCompletedAt holds the string denoting the completed_at field in the database. + FieldCompletedAt = "completed_at" + // FieldFailedAt holds the string denoting the failed_at field in the database. + FieldFailedAt = "failed_at" + // FieldFailedReason holds the string denoting the failed_reason field in the database. + FieldFailedReason = "failed_reason" + // FieldClientIP holds the string denoting the client_ip field in the database. + FieldClientIP = "client_ip" + // FieldSrcHost holds the string denoting the src_host field in the database. + FieldSrcHost = "src_host" + // FieldSrcURL holds the string denoting the src_url field in the database. + FieldSrcURL = "src_url" + // FieldCreatedAt holds the string denoting the created_at field in the database. + FieldCreatedAt = "created_at" + // FieldUpdatedAt holds the string denoting the updated_at field in the database. + FieldUpdatedAt = "updated_at" + // EdgeUser holds the string denoting the user edge name in mutations. + EdgeUser = "user" + // Table holds the table name of the paymentorder in the database. + Table = "payment_orders" + // UserTable is the table that holds the user relation/edge. + UserTable = "payment_orders" + // UserInverseTable is the table name for the User entity. + // It exists in this package in order to avoid circular dependency with the "user" package. + UserInverseTable = "users" + // UserColumn is the table column denoting the user relation/edge. + UserColumn = "user_id" +) + +// Columns holds all SQL columns for paymentorder fields. +var Columns = []string{ + FieldID, + FieldUserID, + FieldUserEmail, + FieldUserName, + FieldUserNotes, + FieldAmount, + FieldPayAmount, + FieldFeeRate, + FieldRechargeCode, + FieldPaymentType, + FieldPaymentTradeNo, + FieldPayURL, + FieldQrCode, + FieldQrCodeImg, + FieldOrderType, + FieldPlanID, + FieldSubscriptionGroupID, + FieldSubscriptionDays, + FieldProviderInstanceID, + FieldStatus, + FieldRefundAmount, + FieldRefundReason, + FieldRefundAt, + FieldForceRefund, + FieldRefundRequestedAt, + FieldRefundRequestReason, + FieldRefundRequestedBy, + FieldExpiresAt, + FieldPaidAt, + FieldCompletedAt, + FieldFailedAt, + FieldFailedReason, + FieldClientIP, + FieldSrcHost, + FieldSrcURL, + FieldCreatedAt, + FieldUpdatedAt, +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + return false +} + +var ( + // UserEmailValidator is a validator for the "user_email" field. It is called by the builders before save. + UserEmailValidator func(string) error + // UserNameValidator is a validator for the "user_name" field. It is called by the builders before save. + UserNameValidator func(string) error + // DefaultFeeRate holds the default value on creation for the "fee_rate" field. + DefaultFeeRate float64 + // RechargeCodeValidator is a validator for the "recharge_code" field. It is called by the builders before save. + RechargeCodeValidator func(string) error + // PaymentTypeValidator is a validator for the "payment_type" field. It is called by the builders before save. + PaymentTypeValidator func(string) error + // PaymentTradeNoValidator is a validator for the "payment_trade_no" field. It is called by the builders before save. + PaymentTradeNoValidator func(string) error + // DefaultOrderType holds the default value on creation for the "order_type" field. + DefaultOrderType string + // OrderTypeValidator is a validator for the "order_type" field. It is called by the builders before save. + OrderTypeValidator func(string) error + // ProviderInstanceIDValidator is a validator for the "provider_instance_id" field. It is called by the builders before save. + ProviderInstanceIDValidator func(string) error + // DefaultStatus holds the default value on creation for the "status" field. + DefaultStatus string + // StatusValidator is a validator for the "status" field. It is called by the builders before save. + StatusValidator func(string) error + // DefaultRefundAmount holds the default value on creation for the "refund_amount" field. + DefaultRefundAmount float64 + // DefaultForceRefund holds the default value on creation for the "force_refund" field. + DefaultForceRefund bool + // RefundRequestedByValidator is a validator for the "refund_requested_by" field. It is called by the builders before save. + RefundRequestedByValidator func(string) error + // ClientIPValidator is a validator for the "client_ip" field. It is called by the builders before save. + ClientIPValidator func(string) error + // SrcHostValidator is a validator for the "src_host" field. It is called by the builders before save. + SrcHostValidator func(string) error + // DefaultCreatedAt holds the default value on creation for the "created_at" field. + DefaultCreatedAt func() time.Time + // DefaultUpdatedAt holds the default value on creation for the "updated_at" field. + DefaultUpdatedAt func() time.Time + // UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field. + UpdateDefaultUpdatedAt func() time.Time +) + +// OrderOption defines the ordering options for the PaymentOrder queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByUserID orders the results by the user_id field. +func ByUserID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUserID, opts...).ToFunc() +} + +// ByUserEmail orders the results by the user_email field. +func ByUserEmail(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUserEmail, opts...).ToFunc() +} + +// ByUserName orders the results by the user_name field. +func ByUserName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUserName, opts...).ToFunc() +} + +// ByUserNotes orders the results by the user_notes field. +func ByUserNotes(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUserNotes, opts...).ToFunc() +} + +// ByAmount orders the results by the amount field. +func ByAmount(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldAmount, opts...).ToFunc() +} + +// ByPayAmount orders the results by the pay_amount field. +func ByPayAmount(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldPayAmount, opts...).ToFunc() +} + +// ByFeeRate orders the results by the fee_rate field. +func ByFeeRate(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldFeeRate, opts...).ToFunc() +} + +// ByRechargeCode orders the results by the recharge_code field. +func ByRechargeCode(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldRechargeCode, opts...).ToFunc() +} + +// ByPaymentType orders the results by the payment_type field. +func ByPaymentType(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldPaymentType, opts...).ToFunc() +} + +// ByPaymentTradeNo orders the results by the payment_trade_no field. +func ByPaymentTradeNo(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldPaymentTradeNo, opts...).ToFunc() +} + +// ByPayURL orders the results by the pay_url field. +func ByPayURL(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldPayURL, opts...).ToFunc() +} + +// ByQrCode orders the results by the qr_code field. +func ByQrCode(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldQrCode, opts...).ToFunc() +} + +// ByQrCodeImg orders the results by the qr_code_img field. +func ByQrCodeImg(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldQrCodeImg, opts...).ToFunc() +} + +// ByOrderType orders the results by the order_type field. +func ByOrderType(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldOrderType, opts...).ToFunc() +} + +// ByPlanID orders the results by the plan_id field. +func ByPlanID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldPlanID, opts...).ToFunc() +} + +// BySubscriptionGroupID orders the results by the subscription_group_id field. +func BySubscriptionGroupID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldSubscriptionGroupID, opts...).ToFunc() +} + +// BySubscriptionDays orders the results by the subscription_days field. +func BySubscriptionDays(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldSubscriptionDays, opts...).ToFunc() +} + +// ByProviderInstanceID orders the results by the provider_instance_id field. +func ByProviderInstanceID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldProviderInstanceID, opts...).ToFunc() +} + +// ByStatus orders the results by the status field. +func ByStatus(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldStatus, opts...).ToFunc() +} + +// ByRefundAmount orders the results by the refund_amount field. +func ByRefundAmount(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldRefundAmount, opts...).ToFunc() +} + +// ByRefundReason orders the results by the refund_reason field. +func ByRefundReason(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldRefundReason, opts...).ToFunc() +} + +// ByRefundAt orders the results by the refund_at field. +func ByRefundAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldRefundAt, opts...).ToFunc() +} + +// ByForceRefund orders the results by the force_refund field. +func ByForceRefund(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldForceRefund, opts...).ToFunc() +} + +// ByRefundRequestedAt orders the results by the refund_requested_at field. +func ByRefundRequestedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldRefundRequestedAt, opts...).ToFunc() +} + +// ByRefundRequestReason orders the results by the refund_request_reason field. +func ByRefundRequestReason(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldRefundRequestReason, opts...).ToFunc() +} + +// ByRefundRequestedBy orders the results by the refund_requested_by field. +func ByRefundRequestedBy(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldRefundRequestedBy, opts...).ToFunc() +} + +// ByExpiresAt orders the results by the expires_at field. +func ByExpiresAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldExpiresAt, opts...).ToFunc() +} + +// ByPaidAt orders the results by the paid_at field. +func ByPaidAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldPaidAt, opts...).ToFunc() +} + +// ByCompletedAt orders the results by the completed_at field. +func ByCompletedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCompletedAt, opts...).ToFunc() +} + +// ByFailedAt orders the results by the failed_at field. +func ByFailedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldFailedAt, opts...).ToFunc() +} + +// ByFailedReason orders the results by the failed_reason field. +func ByFailedReason(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldFailedReason, opts...).ToFunc() +} + +// ByClientIP orders the results by the client_ip field. +func ByClientIP(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClientIP, opts...).ToFunc() +} + +// BySrcHost orders the results by the src_host field. +func BySrcHost(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldSrcHost, opts...).ToFunc() +} + +// BySrcURL orders the results by the src_url field. +func BySrcURL(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldSrcURL, opts...).ToFunc() +} + +// ByCreatedAt orders the results by the created_at field. +func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() +} + +// ByUpdatedAt orders the results by the updated_at field. +func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc() +} + +// ByUserField orders the results by user field. +func ByUserField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newUserStep(), sql.OrderByField(field, opts...)) + } +} +func newUserStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(UserInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn), + ) +} diff --git a/backend/ent/paymentorder/where.go b/backend/ent/paymentorder/where.go new file mode 100644 index 0000000000..0b7b08090a --- /dev/null +++ b/backend/ent/paymentorder/where.go @@ -0,0 +1,2319 @@ +// Code generated by ent, DO NOT EDIT. + +package paymentorder + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/Wei-Shaw/sub2api/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldID, id)) +} + +// UserID applies equality check predicate on the "user_id" field. It's identical to UserIDEQ. +func UserID(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldUserID, v)) +} + +// UserEmail applies equality check predicate on the "user_email" field. It's identical to UserEmailEQ. +func UserEmail(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldUserEmail, v)) +} + +// UserName applies equality check predicate on the "user_name" field. It's identical to UserNameEQ. +func UserName(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldUserName, v)) +} + +// UserNotes applies equality check predicate on the "user_notes" field. It's identical to UserNotesEQ. +func UserNotes(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldUserNotes, v)) +} + +// Amount applies equality check predicate on the "amount" field. It's identical to AmountEQ. +func Amount(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldAmount, v)) +} + +// PayAmount applies equality check predicate on the "pay_amount" field. It's identical to PayAmountEQ. +func PayAmount(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldPayAmount, v)) +} + +// FeeRate applies equality check predicate on the "fee_rate" field. It's identical to FeeRateEQ. +func FeeRate(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldFeeRate, v)) +} + +// RechargeCode applies equality check predicate on the "recharge_code" field. It's identical to RechargeCodeEQ. +func RechargeCode(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldRechargeCode, v)) +} + +// PaymentType applies equality check predicate on the "payment_type" field. It's identical to PaymentTypeEQ. +func PaymentType(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldPaymentType, v)) +} + +// PaymentTradeNo applies equality check predicate on the "payment_trade_no" field. It's identical to PaymentTradeNoEQ. +func PaymentTradeNo(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldPaymentTradeNo, v)) +} + +// PayURL applies equality check predicate on the "pay_url" field. It's identical to PayURLEQ. +func PayURL(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldPayURL, v)) +} + +// QrCode applies equality check predicate on the "qr_code" field. It's identical to QrCodeEQ. +func QrCode(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldQrCode, v)) +} + +// QrCodeImg applies equality check predicate on the "qr_code_img" field. It's identical to QrCodeImgEQ. +func QrCodeImg(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldQrCodeImg, v)) +} + +// OrderType applies equality check predicate on the "order_type" field. It's identical to OrderTypeEQ. +func OrderType(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldOrderType, v)) +} + +// PlanID applies equality check predicate on the "plan_id" field. It's identical to PlanIDEQ. +func PlanID(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldPlanID, v)) +} + +// SubscriptionGroupID applies equality check predicate on the "subscription_group_id" field. It's identical to SubscriptionGroupIDEQ. +func SubscriptionGroupID(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldSubscriptionGroupID, v)) +} + +// SubscriptionDays applies equality check predicate on the "subscription_days" field. It's identical to SubscriptionDaysEQ. +func SubscriptionDays(v int) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldSubscriptionDays, v)) +} + +// ProviderInstanceID applies equality check predicate on the "provider_instance_id" field. It's identical to ProviderInstanceIDEQ. +func ProviderInstanceID(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldProviderInstanceID, v)) +} + +// Status applies equality check predicate on the "status" field. It's identical to StatusEQ. +func Status(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldStatus, v)) +} + +// RefundAmount applies equality check predicate on the "refund_amount" field. It's identical to RefundAmountEQ. +func RefundAmount(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldRefundAmount, v)) +} + +// RefundReason applies equality check predicate on the "refund_reason" field. It's identical to RefundReasonEQ. +func RefundReason(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldRefundReason, v)) +} + +// RefundAt applies equality check predicate on the "refund_at" field. It's identical to RefundAtEQ. +func RefundAt(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldRefundAt, v)) +} + +// ForceRefund applies equality check predicate on the "force_refund" field. It's identical to ForceRefundEQ. +func ForceRefund(v bool) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldForceRefund, v)) +} + +// RefundRequestedAt applies equality check predicate on the "refund_requested_at" field. It's identical to RefundRequestedAtEQ. +func RefundRequestedAt(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldRefundRequestedAt, v)) +} + +// RefundRequestReason applies equality check predicate on the "refund_request_reason" field. It's identical to RefundRequestReasonEQ. +func RefundRequestReason(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldRefundRequestReason, v)) +} + +// RefundRequestedBy applies equality check predicate on the "refund_requested_by" field. It's identical to RefundRequestedByEQ. +func RefundRequestedBy(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldRefundRequestedBy, v)) +} + +// ExpiresAt applies equality check predicate on the "expires_at" field. It's identical to ExpiresAtEQ. +func ExpiresAt(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldExpiresAt, v)) +} + +// PaidAt applies equality check predicate on the "paid_at" field. It's identical to PaidAtEQ. +func PaidAt(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldPaidAt, v)) +} + +// CompletedAt applies equality check predicate on the "completed_at" field. It's identical to CompletedAtEQ. +func CompletedAt(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldCompletedAt, v)) +} + +// FailedAt applies equality check predicate on the "failed_at" field. It's identical to FailedAtEQ. +func FailedAt(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldFailedAt, v)) +} + +// FailedReason applies equality check predicate on the "failed_reason" field. It's identical to FailedReasonEQ. +func FailedReason(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldFailedReason, v)) +} + +// ClientIP applies equality check predicate on the "client_ip" field. It's identical to ClientIPEQ. +func ClientIP(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldClientIP, v)) +} + +// SrcHost applies equality check predicate on the "src_host" field. It's identical to SrcHostEQ. +func SrcHost(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldSrcHost, v)) +} + +// SrcURL applies equality check predicate on the "src_url" field. It's identical to SrcURLEQ. +func SrcURL(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldSrcURL, v)) +} + +// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. +func CreatedAt(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldCreatedAt, v)) +} + +// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ. +func UpdatedAt(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// UserIDEQ applies the EQ predicate on the "user_id" field. +func UserIDEQ(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldUserID, v)) +} + +// UserIDNEQ applies the NEQ predicate on the "user_id" field. +func UserIDNEQ(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldUserID, v)) +} + +// UserIDIn applies the In predicate on the "user_id" field. +func UserIDIn(vs ...int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldUserID, vs...)) +} + +// UserIDNotIn applies the NotIn predicate on the "user_id" field. +func UserIDNotIn(vs ...int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldUserID, vs...)) +} + +// UserEmailEQ applies the EQ predicate on the "user_email" field. +func UserEmailEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldUserEmail, v)) +} + +// UserEmailNEQ applies the NEQ predicate on the "user_email" field. +func UserEmailNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldUserEmail, v)) +} + +// UserEmailIn applies the In predicate on the "user_email" field. +func UserEmailIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldUserEmail, vs...)) +} + +// UserEmailNotIn applies the NotIn predicate on the "user_email" field. +func UserEmailNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldUserEmail, vs...)) +} + +// UserEmailGT applies the GT predicate on the "user_email" field. +func UserEmailGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldUserEmail, v)) +} + +// UserEmailGTE applies the GTE predicate on the "user_email" field. +func UserEmailGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldUserEmail, v)) +} + +// UserEmailLT applies the LT predicate on the "user_email" field. +func UserEmailLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldUserEmail, v)) +} + +// UserEmailLTE applies the LTE predicate on the "user_email" field. +func UserEmailLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldUserEmail, v)) +} + +// UserEmailContains applies the Contains predicate on the "user_email" field. +func UserEmailContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldUserEmail, v)) +} + +// UserEmailHasPrefix applies the HasPrefix predicate on the "user_email" field. +func UserEmailHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldUserEmail, v)) +} + +// UserEmailHasSuffix applies the HasSuffix predicate on the "user_email" field. +func UserEmailHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldUserEmail, v)) +} + +// UserEmailEqualFold applies the EqualFold predicate on the "user_email" field. +func UserEmailEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldUserEmail, v)) +} + +// UserEmailContainsFold applies the ContainsFold predicate on the "user_email" field. +func UserEmailContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldUserEmail, v)) +} + +// UserNameEQ applies the EQ predicate on the "user_name" field. +func UserNameEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldUserName, v)) +} + +// UserNameNEQ applies the NEQ predicate on the "user_name" field. +func UserNameNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldUserName, v)) +} + +// UserNameIn applies the In predicate on the "user_name" field. +func UserNameIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldUserName, vs...)) +} + +// UserNameNotIn applies the NotIn predicate on the "user_name" field. +func UserNameNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldUserName, vs...)) +} + +// UserNameGT applies the GT predicate on the "user_name" field. +func UserNameGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldUserName, v)) +} + +// UserNameGTE applies the GTE predicate on the "user_name" field. +func UserNameGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldUserName, v)) +} + +// UserNameLT applies the LT predicate on the "user_name" field. +func UserNameLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldUserName, v)) +} + +// UserNameLTE applies the LTE predicate on the "user_name" field. +func UserNameLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldUserName, v)) +} + +// UserNameContains applies the Contains predicate on the "user_name" field. +func UserNameContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldUserName, v)) +} + +// UserNameHasPrefix applies the HasPrefix predicate on the "user_name" field. +func UserNameHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldUserName, v)) +} + +// UserNameHasSuffix applies the HasSuffix predicate on the "user_name" field. +func UserNameHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldUserName, v)) +} + +// UserNameEqualFold applies the EqualFold predicate on the "user_name" field. +func UserNameEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldUserName, v)) +} + +// UserNameContainsFold applies the ContainsFold predicate on the "user_name" field. +func UserNameContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldUserName, v)) +} + +// UserNotesEQ applies the EQ predicate on the "user_notes" field. +func UserNotesEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldUserNotes, v)) +} + +// UserNotesNEQ applies the NEQ predicate on the "user_notes" field. +func UserNotesNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldUserNotes, v)) +} + +// UserNotesIn applies the In predicate on the "user_notes" field. +func UserNotesIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldUserNotes, vs...)) +} + +// UserNotesNotIn applies the NotIn predicate on the "user_notes" field. +func UserNotesNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldUserNotes, vs...)) +} + +// UserNotesGT applies the GT predicate on the "user_notes" field. +func UserNotesGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldUserNotes, v)) +} + +// UserNotesGTE applies the GTE predicate on the "user_notes" field. +func UserNotesGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldUserNotes, v)) +} + +// UserNotesLT applies the LT predicate on the "user_notes" field. +func UserNotesLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldUserNotes, v)) +} + +// UserNotesLTE applies the LTE predicate on the "user_notes" field. +func UserNotesLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldUserNotes, v)) +} + +// UserNotesContains applies the Contains predicate on the "user_notes" field. +func UserNotesContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldUserNotes, v)) +} + +// UserNotesHasPrefix applies the HasPrefix predicate on the "user_notes" field. +func UserNotesHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldUserNotes, v)) +} + +// UserNotesHasSuffix applies the HasSuffix predicate on the "user_notes" field. +func UserNotesHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldUserNotes, v)) +} + +// UserNotesIsNil applies the IsNil predicate on the "user_notes" field. +func UserNotesIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldUserNotes)) +} + +// UserNotesNotNil applies the NotNil predicate on the "user_notes" field. +func UserNotesNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldUserNotes)) +} + +// UserNotesEqualFold applies the EqualFold predicate on the "user_notes" field. +func UserNotesEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldUserNotes, v)) +} + +// UserNotesContainsFold applies the ContainsFold predicate on the "user_notes" field. +func UserNotesContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldUserNotes, v)) +} + +// AmountEQ applies the EQ predicate on the "amount" field. +func AmountEQ(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldAmount, v)) +} + +// AmountNEQ applies the NEQ predicate on the "amount" field. +func AmountNEQ(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldAmount, v)) +} + +// AmountIn applies the In predicate on the "amount" field. +func AmountIn(vs ...float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldAmount, vs...)) +} + +// AmountNotIn applies the NotIn predicate on the "amount" field. +func AmountNotIn(vs ...float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldAmount, vs...)) +} + +// AmountGT applies the GT predicate on the "amount" field. +func AmountGT(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldAmount, v)) +} + +// AmountGTE applies the GTE predicate on the "amount" field. +func AmountGTE(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldAmount, v)) +} + +// AmountLT applies the LT predicate on the "amount" field. +func AmountLT(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldAmount, v)) +} + +// AmountLTE applies the LTE predicate on the "amount" field. +func AmountLTE(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldAmount, v)) +} + +// PayAmountEQ applies the EQ predicate on the "pay_amount" field. +func PayAmountEQ(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldPayAmount, v)) +} + +// PayAmountNEQ applies the NEQ predicate on the "pay_amount" field. +func PayAmountNEQ(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldPayAmount, v)) +} + +// PayAmountIn applies the In predicate on the "pay_amount" field. +func PayAmountIn(vs ...float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldPayAmount, vs...)) +} + +// PayAmountNotIn applies the NotIn predicate on the "pay_amount" field. +func PayAmountNotIn(vs ...float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldPayAmount, vs...)) +} + +// PayAmountGT applies the GT predicate on the "pay_amount" field. +func PayAmountGT(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldPayAmount, v)) +} + +// PayAmountGTE applies the GTE predicate on the "pay_amount" field. +func PayAmountGTE(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldPayAmount, v)) +} + +// PayAmountLT applies the LT predicate on the "pay_amount" field. +func PayAmountLT(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldPayAmount, v)) +} + +// PayAmountLTE applies the LTE predicate on the "pay_amount" field. +func PayAmountLTE(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldPayAmount, v)) +} + +// FeeRateEQ applies the EQ predicate on the "fee_rate" field. +func FeeRateEQ(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldFeeRate, v)) +} + +// FeeRateNEQ applies the NEQ predicate on the "fee_rate" field. +func FeeRateNEQ(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldFeeRate, v)) +} + +// FeeRateIn applies the In predicate on the "fee_rate" field. +func FeeRateIn(vs ...float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldFeeRate, vs...)) +} + +// FeeRateNotIn applies the NotIn predicate on the "fee_rate" field. +func FeeRateNotIn(vs ...float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldFeeRate, vs...)) +} + +// FeeRateGT applies the GT predicate on the "fee_rate" field. +func FeeRateGT(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldFeeRate, v)) +} + +// FeeRateGTE applies the GTE predicate on the "fee_rate" field. +func FeeRateGTE(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldFeeRate, v)) +} + +// FeeRateLT applies the LT predicate on the "fee_rate" field. +func FeeRateLT(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldFeeRate, v)) +} + +// FeeRateLTE applies the LTE predicate on the "fee_rate" field. +func FeeRateLTE(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldFeeRate, v)) +} + +// RechargeCodeEQ applies the EQ predicate on the "recharge_code" field. +func RechargeCodeEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldRechargeCode, v)) +} + +// RechargeCodeNEQ applies the NEQ predicate on the "recharge_code" field. +func RechargeCodeNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldRechargeCode, v)) +} + +// RechargeCodeIn applies the In predicate on the "recharge_code" field. +func RechargeCodeIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldRechargeCode, vs...)) +} + +// RechargeCodeNotIn applies the NotIn predicate on the "recharge_code" field. +func RechargeCodeNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldRechargeCode, vs...)) +} + +// RechargeCodeGT applies the GT predicate on the "recharge_code" field. +func RechargeCodeGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldRechargeCode, v)) +} + +// RechargeCodeGTE applies the GTE predicate on the "recharge_code" field. +func RechargeCodeGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldRechargeCode, v)) +} + +// RechargeCodeLT applies the LT predicate on the "recharge_code" field. +func RechargeCodeLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldRechargeCode, v)) +} + +// RechargeCodeLTE applies the LTE predicate on the "recharge_code" field. +func RechargeCodeLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldRechargeCode, v)) +} + +// RechargeCodeContains applies the Contains predicate on the "recharge_code" field. +func RechargeCodeContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldRechargeCode, v)) +} + +// RechargeCodeHasPrefix applies the HasPrefix predicate on the "recharge_code" field. +func RechargeCodeHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldRechargeCode, v)) +} + +// RechargeCodeHasSuffix applies the HasSuffix predicate on the "recharge_code" field. +func RechargeCodeHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldRechargeCode, v)) +} + +// RechargeCodeEqualFold applies the EqualFold predicate on the "recharge_code" field. +func RechargeCodeEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldRechargeCode, v)) +} + +// RechargeCodeContainsFold applies the ContainsFold predicate on the "recharge_code" field. +func RechargeCodeContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldRechargeCode, v)) +} + +// PaymentTypeEQ applies the EQ predicate on the "payment_type" field. +func PaymentTypeEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldPaymentType, v)) +} + +// PaymentTypeNEQ applies the NEQ predicate on the "payment_type" field. +func PaymentTypeNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldPaymentType, v)) +} + +// PaymentTypeIn applies the In predicate on the "payment_type" field. +func PaymentTypeIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldPaymentType, vs...)) +} + +// PaymentTypeNotIn applies the NotIn predicate on the "payment_type" field. +func PaymentTypeNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldPaymentType, vs...)) +} + +// PaymentTypeGT applies the GT predicate on the "payment_type" field. +func PaymentTypeGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldPaymentType, v)) +} + +// PaymentTypeGTE applies the GTE predicate on the "payment_type" field. +func PaymentTypeGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldPaymentType, v)) +} + +// PaymentTypeLT applies the LT predicate on the "payment_type" field. +func PaymentTypeLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldPaymentType, v)) +} + +// PaymentTypeLTE applies the LTE predicate on the "payment_type" field. +func PaymentTypeLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldPaymentType, v)) +} + +// PaymentTypeContains applies the Contains predicate on the "payment_type" field. +func PaymentTypeContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldPaymentType, v)) +} + +// PaymentTypeHasPrefix applies the HasPrefix predicate on the "payment_type" field. +func PaymentTypeHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldPaymentType, v)) +} + +// PaymentTypeHasSuffix applies the HasSuffix predicate on the "payment_type" field. +func PaymentTypeHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldPaymentType, v)) +} + +// PaymentTypeEqualFold applies the EqualFold predicate on the "payment_type" field. +func PaymentTypeEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldPaymentType, v)) +} + +// PaymentTypeContainsFold applies the ContainsFold predicate on the "payment_type" field. +func PaymentTypeContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldPaymentType, v)) +} + +// PaymentTradeNoEQ applies the EQ predicate on the "payment_trade_no" field. +func PaymentTradeNoEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldPaymentTradeNo, v)) +} + +// PaymentTradeNoNEQ applies the NEQ predicate on the "payment_trade_no" field. +func PaymentTradeNoNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldPaymentTradeNo, v)) +} + +// PaymentTradeNoIn applies the In predicate on the "payment_trade_no" field. +func PaymentTradeNoIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldPaymentTradeNo, vs...)) +} + +// PaymentTradeNoNotIn applies the NotIn predicate on the "payment_trade_no" field. +func PaymentTradeNoNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldPaymentTradeNo, vs...)) +} + +// PaymentTradeNoGT applies the GT predicate on the "payment_trade_no" field. +func PaymentTradeNoGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldPaymentTradeNo, v)) +} + +// PaymentTradeNoGTE applies the GTE predicate on the "payment_trade_no" field. +func PaymentTradeNoGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldPaymentTradeNo, v)) +} + +// PaymentTradeNoLT applies the LT predicate on the "payment_trade_no" field. +func PaymentTradeNoLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldPaymentTradeNo, v)) +} + +// PaymentTradeNoLTE applies the LTE predicate on the "payment_trade_no" field. +func PaymentTradeNoLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldPaymentTradeNo, v)) +} + +// PaymentTradeNoContains applies the Contains predicate on the "payment_trade_no" field. +func PaymentTradeNoContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldPaymentTradeNo, v)) +} + +// PaymentTradeNoHasPrefix applies the HasPrefix predicate on the "payment_trade_no" field. +func PaymentTradeNoHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldPaymentTradeNo, v)) +} + +// PaymentTradeNoHasSuffix applies the HasSuffix predicate on the "payment_trade_no" field. +func PaymentTradeNoHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldPaymentTradeNo, v)) +} + +// PaymentTradeNoEqualFold applies the EqualFold predicate on the "payment_trade_no" field. +func PaymentTradeNoEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldPaymentTradeNo, v)) +} + +// PaymentTradeNoContainsFold applies the ContainsFold predicate on the "payment_trade_no" field. +func PaymentTradeNoContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldPaymentTradeNo, v)) +} + +// PayURLEQ applies the EQ predicate on the "pay_url" field. +func PayURLEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldPayURL, v)) +} + +// PayURLNEQ applies the NEQ predicate on the "pay_url" field. +func PayURLNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldPayURL, v)) +} + +// PayURLIn applies the In predicate on the "pay_url" field. +func PayURLIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldPayURL, vs...)) +} + +// PayURLNotIn applies the NotIn predicate on the "pay_url" field. +func PayURLNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldPayURL, vs...)) +} + +// PayURLGT applies the GT predicate on the "pay_url" field. +func PayURLGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldPayURL, v)) +} + +// PayURLGTE applies the GTE predicate on the "pay_url" field. +func PayURLGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldPayURL, v)) +} + +// PayURLLT applies the LT predicate on the "pay_url" field. +func PayURLLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldPayURL, v)) +} + +// PayURLLTE applies the LTE predicate on the "pay_url" field. +func PayURLLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldPayURL, v)) +} + +// PayURLContains applies the Contains predicate on the "pay_url" field. +func PayURLContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldPayURL, v)) +} + +// PayURLHasPrefix applies the HasPrefix predicate on the "pay_url" field. +func PayURLHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldPayURL, v)) +} + +// PayURLHasSuffix applies the HasSuffix predicate on the "pay_url" field. +func PayURLHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldPayURL, v)) +} + +// PayURLIsNil applies the IsNil predicate on the "pay_url" field. +func PayURLIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldPayURL)) +} + +// PayURLNotNil applies the NotNil predicate on the "pay_url" field. +func PayURLNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldPayURL)) +} + +// PayURLEqualFold applies the EqualFold predicate on the "pay_url" field. +func PayURLEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldPayURL, v)) +} + +// PayURLContainsFold applies the ContainsFold predicate on the "pay_url" field. +func PayURLContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldPayURL, v)) +} + +// QrCodeEQ applies the EQ predicate on the "qr_code" field. +func QrCodeEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldQrCode, v)) +} + +// QrCodeNEQ applies the NEQ predicate on the "qr_code" field. +func QrCodeNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldQrCode, v)) +} + +// QrCodeIn applies the In predicate on the "qr_code" field. +func QrCodeIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldQrCode, vs...)) +} + +// QrCodeNotIn applies the NotIn predicate on the "qr_code" field. +func QrCodeNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldQrCode, vs...)) +} + +// QrCodeGT applies the GT predicate on the "qr_code" field. +func QrCodeGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldQrCode, v)) +} + +// QrCodeGTE applies the GTE predicate on the "qr_code" field. +func QrCodeGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldQrCode, v)) +} + +// QrCodeLT applies the LT predicate on the "qr_code" field. +func QrCodeLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldQrCode, v)) +} + +// QrCodeLTE applies the LTE predicate on the "qr_code" field. +func QrCodeLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldQrCode, v)) +} + +// QrCodeContains applies the Contains predicate on the "qr_code" field. +func QrCodeContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldQrCode, v)) +} + +// QrCodeHasPrefix applies the HasPrefix predicate on the "qr_code" field. +func QrCodeHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldQrCode, v)) +} + +// QrCodeHasSuffix applies the HasSuffix predicate on the "qr_code" field. +func QrCodeHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldQrCode, v)) +} + +// QrCodeIsNil applies the IsNil predicate on the "qr_code" field. +func QrCodeIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldQrCode)) +} + +// QrCodeNotNil applies the NotNil predicate on the "qr_code" field. +func QrCodeNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldQrCode)) +} + +// QrCodeEqualFold applies the EqualFold predicate on the "qr_code" field. +func QrCodeEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldQrCode, v)) +} + +// QrCodeContainsFold applies the ContainsFold predicate on the "qr_code" field. +func QrCodeContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldQrCode, v)) +} + +// QrCodeImgEQ applies the EQ predicate on the "qr_code_img" field. +func QrCodeImgEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldQrCodeImg, v)) +} + +// QrCodeImgNEQ applies the NEQ predicate on the "qr_code_img" field. +func QrCodeImgNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldQrCodeImg, v)) +} + +// QrCodeImgIn applies the In predicate on the "qr_code_img" field. +func QrCodeImgIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldQrCodeImg, vs...)) +} + +// QrCodeImgNotIn applies the NotIn predicate on the "qr_code_img" field. +func QrCodeImgNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldQrCodeImg, vs...)) +} + +// QrCodeImgGT applies the GT predicate on the "qr_code_img" field. +func QrCodeImgGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldQrCodeImg, v)) +} + +// QrCodeImgGTE applies the GTE predicate on the "qr_code_img" field. +func QrCodeImgGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldQrCodeImg, v)) +} + +// QrCodeImgLT applies the LT predicate on the "qr_code_img" field. +func QrCodeImgLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldQrCodeImg, v)) +} + +// QrCodeImgLTE applies the LTE predicate on the "qr_code_img" field. +func QrCodeImgLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldQrCodeImg, v)) +} + +// QrCodeImgContains applies the Contains predicate on the "qr_code_img" field. +func QrCodeImgContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldQrCodeImg, v)) +} + +// QrCodeImgHasPrefix applies the HasPrefix predicate on the "qr_code_img" field. +func QrCodeImgHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldQrCodeImg, v)) +} + +// QrCodeImgHasSuffix applies the HasSuffix predicate on the "qr_code_img" field. +func QrCodeImgHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldQrCodeImg, v)) +} + +// QrCodeImgIsNil applies the IsNil predicate on the "qr_code_img" field. +func QrCodeImgIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldQrCodeImg)) +} + +// QrCodeImgNotNil applies the NotNil predicate on the "qr_code_img" field. +func QrCodeImgNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldQrCodeImg)) +} + +// QrCodeImgEqualFold applies the EqualFold predicate on the "qr_code_img" field. +func QrCodeImgEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldQrCodeImg, v)) +} + +// QrCodeImgContainsFold applies the ContainsFold predicate on the "qr_code_img" field. +func QrCodeImgContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldQrCodeImg, v)) +} + +// OrderTypeEQ applies the EQ predicate on the "order_type" field. +func OrderTypeEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldOrderType, v)) +} + +// OrderTypeNEQ applies the NEQ predicate on the "order_type" field. +func OrderTypeNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldOrderType, v)) +} + +// OrderTypeIn applies the In predicate on the "order_type" field. +func OrderTypeIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldOrderType, vs...)) +} + +// OrderTypeNotIn applies the NotIn predicate on the "order_type" field. +func OrderTypeNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldOrderType, vs...)) +} + +// OrderTypeGT applies the GT predicate on the "order_type" field. +func OrderTypeGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldOrderType, v)) +} + +// OrderTypeGTE applies the GTE predicate on the "order_type" field. +func OrderTypeGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldOrderType, v)) +} + +// OrderTypeLT applies the LT predicate on the "order_type" field. +func OrderTypeLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldOrderType, v)) +} + +// OrderTypeLTE applies the LTE predicate on the "order_type" field. +func OrderTypeLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldOrderType, v)) +} + +// OrderTypeContains applies the Contains predicate on the "order_type" field. +func OrderTypeContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldOrderType, v)) +} + +// OrderTypeHasPrefix applies the HasPrefix predicate on the "order_type" field. +func OrderTypeHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldOrderType, v)) +} + +// OrderTypeHasSuffix applies the HasSuffix predicate on the "order_type" field. +func OrderTypeHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldOrderType, v)) +} + +// OrderTypeEqualFold applies the EqualFold predicate on the "order_type" field. +func OrderTypeEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldOrderType, v)) +} + +// OrderTypeContainsFold applies the ContainsFold predicate on the "order_type" field. +func OrderTypeContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldOrderType, v)) +} + +// PlanIDEQ applies the EQ predicate on the "plan_id" field. +func PlanIDEQ(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldPlanID, v)) +} + +// PlanIDNEQ applies the NEQ predicate on the "plan_id" field. +func PlanIDNEQ(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldPlanID, v)) +} + +// PlanIDIn applies the In predicate on the "plan_id" field. +func PlanIDIn(vs ...int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldPlanID, vs...)) +} + +// PlanIDNotIn applies the NotIn predicate on the "plan_id" field. +func PlanIDNotIn(vs ...int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldPlanID, vs...)) +} + +// PlanIDGT applies the GT predicate on the "plan_id" field. +func PlanIDGT(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldPlanID, v)) +} + +// PlanIDGTE applies the GTE predicate on the "plan_id" field. +func PlanIDGTE(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldPlanID, v)) +} + +// PlanIDLT applies the LT predicate on the "plan_id" field. +func PlanIDLT(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldPlanID, v)) +} + +// PlanIDLTE applies the LTE predicate on the "plan_id" field. +func PlanIDLTE(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldPlanID, v)) +} + +// PlanIDIsNil applies the IsNil predicate on the "plan_id" field. +func PlanIDIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldPlanID)) +} + +// PlanIDNotNil applies the NotNil predicate on the "plan_id" field. +func PlanIDNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldPlanID)) +} + +// SubscriptionGroupIDEQ applies the EQ predicate on the "subscription_group_id" field. +func SubscriptionGroupIDEQ(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldSubscriptionGroupID, v)) +} + +// SubscriptionGroupIDNEQ applies the NEQ predicate on the "subscription_group_id" field. +func SubscriptionGroupIDNEQ(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldSubscriptionGroupID, v)) +} + +// SubscriptionGroupIDIn applies the In predicate on the "subscription_group_id" field. +func SubscriptionGroupIDIn(vs ...int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldSubscriptionGroupID, vs...)) +} + +// SubscriptionGroupIDNotIn applies the NotIn predicate on the "subscription_group_id" field. +func SubscriptionGroupIDNotIn(vs ...int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldSubscriptionGroupID, vs...)) +} + +// SubscriptionGroupIDGT applies the GT predicate on the "subscription_group_id" field. +func SubscriptionGroupIDGT(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldSubscriptionGroupID, v)) +} + +// SubscriptionGroupIDGTE applies the GTE predicate on the "subscription_group_id" field. +func SubscriptionGroupIDGTE(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldSubscriptionGroupID, v)) +} + +// SubscriptionGroupIDLT applies the LT predicate on the "subscription_group_id" field. +func SubscriptionGroupIDLT(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldSubscriptionGroupID, v)) +} + +// SubscriptionGroupIDLTE applies the LTE predicate on the "subscription_group_id" field. +func SubscriptionGroupIDLTE(v int64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldSubscriptionGroupID, v)) +} + +// SubscriptionGroupIDIsNil applies the IsNil predicate on the "subscription_group_id" field. +func SubscriptionGroupIDIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldSubscriptionGroupID)) +} + +// SubscriptionGroupIDNotNil applies the NotNil predicate on the "subscription_group_id" field. +func SubscriptionGroupIDNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldSubscriptionGroupID)) +} + +// SubscriptionDaysEQ applies the EQ predicate on the "subscription_days" field. +func SubscriptionDaysEQ(v int) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldSubscriptionDays, v)) +} + +// SubscriptionDaysNEQ applies the NEQ predicate on the "subscription_days" field. +func SubscriptionDaysNEQ(v int) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldSubscriptionDays, v)) +} + +// SubscriptionDaysIn applies the In predicate on the "subscription_days" field. +func SubscriptionDaysIn(vs ...int) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldSubscriptionDays, vs...)) +} + +// SubscriptionDaysNotIn applies the NotIn predicate on the "subscription_days" field. +func SubscriptionDaysNotIn(vs ...int) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldSubscriptionDays, vs...)) +} + +// SubscriptionDaysGT applies the GT predicate on the "subscription_days" field. +func SubscriptionDaysGT(v int) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldSubscriptionDays, v)) +} + +// SubscriptionDaysGTE applies the GTE predicate on the "subscription_days" field. +func SubscriptionDaysGTE(v int) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldSubscriptionDays, v)) +} + +// SubscriptionDaysLT applies the LT predicate on the "subscription_days" field. +func SubscriptionDaysLT(v int) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldSubscriptionDays, v)) +} + +// SubscriptionDaysLTE applies the LTE predicate on the "subscription_days" field. +func SubscriptionDaysLTE(v int) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldSubscriptionDays, v)) +} + +// SubscriptionDaysIsNil applies the IsNil predicate on the "subscription_days" field. +func SubscriptionDaysIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldSubscriptionDays)) +} + +// SubscriptionDaysNotNil applies the NotNil predicate on the "subscription_days" field. +func SubscriptionDaysNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldSubscriptionDays)) +} + +// ProviderInstanceIDEQ applies the EQ predicate on the "provider_instance_id" field. +func ProviderInstanceIDEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldProviderInstanceID, v)) +} + +// ProviderInstanceIDNEQ applies the NEQ predicate on the "provider_instance_id" field. +func ProviderInstanceIDNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldProviderInstanceID, v)) +} + +// ProviderInstanceIDIn applies the In predicate on the "provider_instance_id" field. +func ProviderInstanceIDIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldProviderInstanceID, vs...)) +} + +// ProviderInstanceIDNotIn applies the NotIn predicate on the "provider_instance_id" field. +func ProviderInstanceIDNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldProviderInstanceID, vs...)) +} + +// ProviderInstanceIDGT applies the GT predicate on the "provider_instance_id" field. +func ProviderInstanceIDGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldProviderInstanceID, v)) +} + +// ProviderInstanceIDGTE applies the GTE predicate on the "provider_instance_id" field. +func ProviderInstanceIDGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldProviderInstanceID, v)) +} + +// ProviderInstanceIDLT applies the LT predicate on the "provider_instance_id" field. +func ProviderInstanceIDLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldProviderInstanceID, v)) +} + +// ProviderInstanceIDLTE applies the LTE predicate on the "provider_instance_id" field. +func ProviderInstanceIDLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldProviderInstanceID, v)) +} + +// ProviderInstanceIDContains applies the Contains predicate on the "provider_instance_id" field. +func ProviderInstanceIDContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldProviderInstanceID, v)) +} + +// ProviderInstanceIDHasPrefix applies the HasPrefix predicate on the "provider_instance_id" field. +func ProviderInstanceIDHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldProviderInstanceID, v)) +} + +// ProviderInstanceIDHasSuffix applies the HasSuffix predicate on the "provider_instance_id" field. +func ProviderInstanceIDHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldProviderInstanceID, v)) +} + +// ProviderInstanceIDIsNil applies the IsNil predicate on the "provider_instance_id" field. +func ProviderInstanceIDIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldProviderInstanceID)) +} + +// ProviderInstanceIDNotNil applies the NotNil predicate on the "provider_instance_id" field. +func ProviderInstanceIDNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldProviderInstanceID)) +} + +// ProviderInstanceIDEqualFold applies the EqualFold predicate on the "provider_instance_id" field. +func ProviderInstanceIDEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldProviderInstanceID, v)) +} + +// ProviderInstanceIDContainsFold applies the ContainsFold predicate on the "provider_instance_id" field. +func ProviderInstanceIDContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldProviderInstanceID, v)) +} + +// StatusEQ applies the EQ predicate on the "status" field. +func StatusEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldStatus, v)) +} + +// StatusNEQ applies the NEQ predicate on the "status" field. +func StatusNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldStatus, v)) +} + +// StatusIn applies the In predicate on the "status" field. +func StatusIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldStatus, vs...)) +} + +// StatusNotIn applies the NotIn predicate on the "status" field. +func StatusNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldStatus, vs...)) +} + +// StatusGT applies the GT predicate on the "status" field. +func StatusGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldStatus, v)) +} + +// StatusGTE applies the GTE predicate on the "status" field. +func StatusGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldStatus, v)) +} + +// StatusLT applies the LT predicate on the "status" field. +func StatusLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldStatus, v)) +} + +// StatusLTE applies the LTE predicate on the "status" field. +func StatusLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldStatus, v)) +} + +// StatusContains applies the Contains predicate on the "status" field. +func StatusContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldStatus, v)) +} + +// StatusHasPrefix applies the HasPrefix predicate on the "status" field. +func StatusHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldStatus, v)) +} + +// StatusHasSuffix applies the HasSuffix predicate on the "status" field. +func StatusHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldStatus, v)) +} + +// StatusEqualFold applies the EqualFold predicate on the "status" field. +func StatusEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldStatus, v)) +} + +// StatusContainsFold applies the ContainsFold predicate on the "status" field. +func StatusContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldStatus, v)) +} + +// RefundAmountEQ applies the EQ predicate on the "refund_amount" field. +func RefundAmountEQ(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldRefundAmount, v)) +} + +// RefundAmountNEQ applies the NEQ predicate on the "refund_amount" field. +func RefundAmountNEQ(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldRefundAmount, v)) +} + +// RefundAmountIn applies the In predicate on the "refund_amount" field. +func RefundAmountIn(vs ...float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldRefundAmount, vs...)) +} + +// RefundAmountNotIn applies the NotIn predicate on the "refund_amount" field. +func RefundAmountNotIn(vs ...float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldRefundAmount, vs...)) +} + +// RefundAmountGT applies the GT predicate on the "refund_amount" field. +func RefundAmountGT(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldRefundAmount, v)) +} + +// RefundAmountGTE applies the GTE predicate on the "refund_amount" field. +func RefundAmountGTE(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldRefundAmount, v)) +} + +// RefundAmountLT applies the LT predicate on the "refund_amount" field. +func RefundAmountLT(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldRefundAmount, v)) +} + +// RefundAmountLTE applies the LTE predicate on the "refund_amount" field. +func RefundAmountLTE(v float64) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldRefundAmount, v)) +} + +// RefundReasonEQ applies the EQ predicate on the "refund_reason" field. +func RefundReasonEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldRefundReason, v)) +} + +// RefundReasonNEQ applies the NEQ predicate on the "refund_reason" field. +func RefundReasonNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldRefundReason, v)) +} + +// RefundReasonIn applies the In predicate on the "refund_reason" field. +func RefundReasonIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldRefundReason, vs...)) +} + +// RefundReasonNotIn applies the NotIn predicate on the "refund_reason" field. +func RefundReasonNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldRefundReason, vs...)) +} + +// RefundReasonGT applies the GT predicate on the "refund_reason" field. +func RefundReasonGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldRefundReason, v)) +} + +// RefundReasonGTE applies the GTE predicate on the "refund_reason" field. +func RefundReasonGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldRefundReason, v)) +} + +// RefundReasonLT applies the LT predicate on the "refund_reason" field. +func RefundReasonLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldRefundReason, v)) +} + +// RefundReasonLTE applies the LTE predicate on the "refund_reason" field. +func RefundReasonLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldRefundReason, v)) +} + +// RefundReasonContains applies the Contains predicate on the "refund_reason" field. +func RefundReasonContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldRefundReason, v)) +} + +// RefundReasonHasPrefix applies the HasPrefix predicate on the "refund_reason" field. +func RefundReasonHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldRefundReason, v)) +} + +// RefundReasonHasSuffix applies the HasSuffix predicate on the "refund_reason" field. +func RefundReasonHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldRefundReason, v)) +} + +// RefundReasonIsNil applies the IsNil predicate on the "refund_reason" field. +func RefundReasonIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldRefundReason)) +} + +// RefundReasonNotNil applies the NotNil predicate on the "refund_reason" field. +func RefundReasonNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldRefundReason)) +} + +// RefundReasonEqualFold applies the EqualFold predicate on the "refund_reason" field. +func RefundReasonEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldRefundReason, v)) +} + +// RefundReasonContainsFold applies the ContainsFold predicate on the "refund_reason" field. +func RefundReasonContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldRefundReason, v)) +} + +// RefundAtEQ applies the EQ predicate on the "refund_at" field. +func RefundAtEQ(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldRefundAt, v)) +} + +// RefundAtNEQ applies the NEQ predicate on the "refund_at" field. +func RefundAtNEQ(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldRefundAt, v)) +} + +// RefundAtIn applies the In predicate on the "refund_at" field. +func RefundAtIn(vs ...time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldRefundAt, vs...)) +} + +// RefundAtNotIn applies the NotIn predicate on the "refund_at" field. +func RefundAtNotIn(vs ...time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldRefundAt, vs...)) +} + +// RefundAtGT applies the GT predicate on the "refund_at" field. +func RefundAtGT(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldRefundAt, v)) +} + +// RefundAtGTE applies the GTE predicate on the "refund_at" field. +func RefundAtGTE(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldRefundAt, v)) +} + +// RefundAtLT applies the LT predicate on the "refund_at" field. +func RefundAtLT(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldRefundAt, v)) +} + +// RefundAtLTE applies the LTE predicate on the "refund_at" field. +func RefundAtLTE(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldRefundAt, v)) +} + +// RefundAtIsNil applies the IsNil predicate on the "refund_at" field. +func RefundAtIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldRefundAt)) +} + +// RefundAtNotNil applies the NotNil predicate on the "refund_at" field. +func RefundAtNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldRefundAt)) +} + +// ForceRefundEQ applies the EQ predicate on the "force_refund" field. +func ForceRefundEQ(v bool) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldForceRefund, v)) +} + +// ForceRefundNEQ applies the NEQ predicate on the "force_refund" field. +func ForceRefundNEQ(v bool) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldForceRefund, v)) +} + +// RefundRequestedAtEQ applies the EQ predicate on the "refund_requested_at" field. +func RefundRequestedAtEQ(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldRefundRequestedAt, v)) +} + +// RefundRequestedAtNEQ applies the NEQ predicate on the "refund_requested_at" field. +func RefundRequestedAtNEQ(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldRefundRequestedAt, v)) +} + +// RefundRequestedAtIn applies the In predicate on the "refund_requested_at" field. +func RefundRequestedAtIn(vs ...time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldRefundRequestedAt, vs...)) +} + +// RefundRequestedAtNotIn applies the NotIn predicate on the "refund_requested_at" field. +func RefundRequestedAtNotIn(vs ...time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldRefundRequestedAt, vs...)) +} + +// RefundRequestedAtGT applies the GT predicate on the "refund_requested_at" field. +func RefundRequestedAtGT(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldRefundRequestedAt, v)) +} + +// RefundRequestedAtGTE applies the GTE predicate on the "refund_requested_at" field. +func RefundRequestedAtGTE(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldRefundRequestedAt, v)) +} + +// RefundRequestedAtLT applies the LT predicate on the "refund_requested_at" field. +func RefundRequestedAtLT(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldRefundRequestedAt, v)) +} + +// RefundRequestedAtLTE applies the LTE predicate on the "refund_requested_at" field. +func RefundRequestedAtLTE(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldRefundRequestedAt, v)) +} + +// RefundRequestedAtIsNil applies the IsNil predicate on the "refund_requested_at" field. +func RefundRequestedAtIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldRefundRequestedAt)) +} + +// RefundRequestedAtNotNil applies the NotNil predicate on the "refund_requested_at" field. +func RefundRequestedAtNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldRefundRequestedAt)) +} + +// RefundRequestReasonEQ applies the EQ predicate on the "refund_request_reason" field. +func RefundRequestReasonEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldRefundRequestReason, v)) +} + +// RefundRequestReasonNEQ applies the NEQ predicate on the "refund_request_reason" field. +func RefundRequestReasonNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldRefundRequestReason, v)) +} + +// RefundRequestReasonIn applies the In predicate on the "refund_request_reason" field. +func RefundRequestReasonIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldRefundRequestReason, vs...)) +} + +// RefundRequestReasonNotIn applies the NotIn predicate on the "refund_request_reason" field. +func RefundRequestReasonNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldRefundRequestReason, vs...)) +} + +// RefundRequestReasonGT applies the GT predicate on the "refund_request_reason" field. +func RefundRequestReasonGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldRefundRequestReason, v)) +} + +// RefundRequestReasonGTE applies the GTE predicate on the "refund_request_reason" field. +func RefundRequestReasonGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldRefundRequestReason, v)) +} + +// RefundRequestReasonLT applies the LT predicate on the "refund_request_reason" field. +func RefundRequestReasonLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldRefundRequestReason, v)) +} + +// RefundRequestReasonLTE applies the LTE predicate on the "refund_request_reason" field. +func RefundRequestReasonLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldRefundRequestReason, v)) +} + +// RefundRequestReasonContains applies the Contains predicate on the "refund_request_reason" field. +func RefundRequestReasonContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldRefundRequestReason, v)) +} + +// RefundRequestReasonHasPrefix applies the HasPrefix predicate on the "refund_request_reason" field. +func RefundRequestReasonHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldRefundRequestReason, v)) +} + +// RefundRequestReasonHasSuffix applies the HasSuffix predicate on the "refund_request_reason" field. +func RefundRequestReasonHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldRefundRequestReason, v)) +} + +// RefundRequestReasonIsNil applies the IsNil predicate on the "refund_request_reason" field. +func RefundRequestReasonIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldRefundRequestReason)) +} + +// RefundRequestReasonNotNil applies the NotNil predicate on the "refund_request_reason" field. +func RefundRequestReasonNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldRefundRequestReason)) +} + +// RefundRequestReasonEqualFold applies the EqualFold predicate on the "refund_request_reason" field. +func RefundRequestReasonEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldRefundRequestReason, v)) +} + +// RefundRequestReasonContainsFold applies the ContainsFold predicate on the "refund_request_reason" field. +func RefundRequestReasonContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldRefundRequestReason, v)) +} + +// RefundRequestedByEQ applies the EQ predicate on the "refund_requested_by" field. +func RefundRequestedByEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldRefundRequestedBy, v)) +} + +// RefundRequestedByNEQ applies the NEQ predicate on the "refund_requested_by" field. +func RefundRequestedByNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldRefundRequestedBy, v)) +} + +// RefundRequestedByIn applies the In predicate on the "refund_requested_by" field. +func RefundRequestedByIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldRefundRequestedBy, vs...)) +} + +// RefundRequestedByNotIn applies the NotIn predicate on the "refund_requested_by" field. +func RefundRequestedByNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldRefundRequestedBy, vs...)) +} + +// RefundRequestedByGT applies the GT predicate on the "refund_requested_by" field. +func RefundRequestedByGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldRefundRequestedBy, v)) +} + +// RefundRequestedByGTE applies the GTE predicate on the "refund_requested_by" field. +func RefundRequestedByGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldRefundRequestedBy, v)) +} + +// RefundRequestedByLT applies the LT predicate on the "refund_requested_by" field. +func RefundRequestedByLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldRefundRequestedBy, v)) +} + +// RefundRequestedByLTE applies the LTE predicate on the "refund_requested_by" field. +func RefundRequestedByLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldRefundRequestedBy, v)) +} + +// RefundRequestedByContains applies the Contains predicate on the "refund_requested_by" field. +func RefundRequestedByContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldRefundRequestedBy, v)) +} + +// RefundRequestedByHasPrefix applies the HasPrefix predicate on the "refund_requested_by" field. +func RefundRequestedByHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldRefundRequestedBy, v)) +} + +// RefundRequestedByHasSuffix applies the HasSuffix predicate on the "refund_requested_by" field. +func RefundRequestedByHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldRefundRequestedBy, v)) +} + +// RefundRequestedByIsNil applies the IsNil predicate on the "refund_requested_by" field. +func RefundRequestedByIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldRefundRequestedBy)) +} + +// RefundRequestedByNotNil applies the NotNil predicate on the "refund_requested_by" field. +func RefundRequestedByNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldRefundRequestedBy)) +} + +// RefundRequestedByEqualFold applies the EqualFold predicate on the "refund_requested_by" field. +func RefundRequestedByEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldRefundRequestedBy, v)) +} + +// RefundRequestedByContainsFold applies the ContainsFold predicate on the "refund_requested_by" field. +func RefundRequestedByContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldRefundRequestedBy, v)) +} + +// ExpiresAtEQ applies the EQ predicate on the "expires_at" field. +func ExpiresAtEQ(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldExpiresAt, v)) +} + +// ExpiresAtNEQ applies the NEQ predicate on the "expires_at" field. +func ExpiresAtNEQ(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldExpiresAt, v)) +} + +// ExpiresAtIn applies the In predicate on the "expires_at" field. +func ExpiresAtIn(vs ...time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldExpiresAt, vs...)) +} + +// ExpiresAtNotIn applies the NotIn predicate on the "expires_at" field. +func ExpiresAtNotIn(vs ...time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldExpiresAt, vs...)) +} + +// ExpiresAtGT applies the GT predicate on the "expires_at" field. +func ExpiresAtGT(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldExpiresAt, v)) +} + +// ExpiresAtGTE applies the GTE predicate on the "expires_at" field. +func ExpiresAtGTE(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldExpiresAt, v)) +} + +// ExpiresAtLT applies the LT predicate on the "expires_at" field. +func ExpiresAtLT(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldExpiresAt, v)) +} + +// ExpiresAtLTE applies the LTE predicate on the "expires_at" field. +func ExpiresAtLTE(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldExpiresAt, v)) +} + +// PaidAtEQ applies the EQ predicate on the "paid_at" field. +func PaidAtEQ(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldPaidAt, v)) +} + +// PaidAtNEQ applies the NEQ predicate on the "paid_at" field. +func PaidAtNEQ(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldPaidAt, v)) +} + +// PaidAtIn applies the In predicate on the "paid_at" field. +func PaidAtIn(vs ...time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldPaidAt, vs...)) +} + +// PaidAtNotIn applies the NotIn predicate on the "paid_at" field. +func PaidAtNotIn(vs ...time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldPaidAt, vs...)) +} + +// PaidAtGT applies the GT predicate on the "paid_at" field. +func PaidAtGT(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldPaidAt, v)) +} + +// PaidAtGTE applies the GTE predicate on the "paid_at" field. +func PaidAtGTE(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldPaidAt, v)) +} + +// PaidAtLT applies the LT predicate on the "paid_at" field. +func PaidAtLT(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldPaidAt, v)) +} + +// PaidAtLTE applies the LTE predicate on the "paid_at" field. +func PaidAtLTE(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldPaidAt, v)) +} + +// PaidAtIsNil applies the IsNil predicate on the "paid_at" field. +func PaidAtIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldPaidAt)) +} + +// PaidAtNotNil applies the NotNil predicate on the "paid_at" field. +func PaidAtNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldPaidAt)) +} + +// CompletedAtEQ applies the EQ predicate on the "completed_at" field. +func CompletedAtEQ(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldCompletedAt, v)) +} + +// CompletedAtNEQ applies the NEQ predicate on the "completed_at" field. +func CompletedAtNEQ(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldCompletedAt, v)) +} + +// CompletedAtIn applies the In predicate on the "completed_at" field. +func CompletedAtIn(vs ...time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldCompletedAt, vs...)) +} + +// CompletedAtNotIn applies the NotIn predicate on the "completed_at" field. +func CompletedAtNotIn(vs ...time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldCompletedAt, vs...)) +} + +// CompletedAtGT applies the GT predicate on the "completed_at" field. +func CompletedAtGT(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldCompletedAt, v)) +} + +// CompletedAtGTE applies the GTE predicate on the "completed_at" field. +func CompletedAtGTE(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldCompletedAt, v)) +} + +// CompletedAtLT applies the LT predicate on the "completed_at" field. +func CompletedAtLT(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldCompletedAt, v)) +} + +// CompletedAtLTE applies the LTE predicate on the "completed_at" field. +func CompletedAtLTE(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldCompletedAt, v)) +} + +// CompletedAtIsNil applies the IsNil predicate on the "completed_at" field. +func CompletedAtIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldCompletedAt)) +} + +// CompletedAtNotNil applies the NotNil predicate on the "completed_at" field. +func CompletedAtNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldCompletedAt)) +} + +// FailedAtEQ applies the EQ predicate on the "failed_at" field. +func FailedAtEQ(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldFailedAt, v)) +} + +// FailedAtNEQ applies the NEQ predicate on the "failed_at" field. +func FailedAtNEQ(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldFailedAt, v)) +} + +// FailedAtIn applies the In predicate on the "failed_at" field. +func FailedAtIn(vs ...time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldFailedAt, vs...)) +} + +// FailedAtNotIn applies the NotIn predicate on the "failed_at" field. +func FailedAtNotIn(vs ...time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldFailedAt, vs...)) +} + +// FailedAtGT applies the GT predicate on the "failed_at" field. +func FailedAtGT(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldFailedAt, v)) +} + +// FailedAtGTE applies the GTE predicate on the "failed_at" field. +func FailedAtGTE(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldFailedAt, v)) +} + +// FailedAtLT applies the LT predicate on the "failed_at" field. +func FailedAtLT(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldFailedAt, v)) +} + +// FailedAtLTE applies the LTE predicate on the "failed_at" field. +func FailedAtLTE(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldFailedAt, v)) +} + +// FailedAtIsNil applies the IsNil predicate on the "failed_at" field. +func FailedAtIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldFailedAt)) +} + +// FailedAtNotNil applies the NotNil predicate on the "failed_at" field. +func FailedAtNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldFailedAt)) +} + +// FailedReasonEQ applies the EQ predicate on the "failed_reason" field. +func FailedReasonEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldFailedReason, v)) +} + +// FailedReasonNEQ applies the NEQ predicate on the "failed_reason" field. +func FailedReasonNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldFailedReason, v)) +} + +// FailedReasonIn applies the In predicate on the "failed_reason" field. +func FailedReasonIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldFailedReason, vs...)) +} + +// FailedReasonNotIn applies the NotIn predicate on the "failed_reason" field. +func FailedReasonNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldFailedReason, vs...)) +} + +// FailedReasonGT applies the GT predicate on the "failed_reason" field. +func FailedReasonGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldFailedReason, v)) +} + +// FailedReasonGTE applies the GTE predicate on the "failed_reason" field. +func FailedReasonGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldFailedReason, v)) +} + +// FailedReasonLT applies the LT predicate on the "failed_reason" field. +func FailedReasonLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldFailedReason, v)) +} + +// FailedReasonLTE applies the LTE predicate on the "failed_reason" field. +func FailedReasonLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldFailedReason, v)) +} + +// FailedReasonContains applies the Contains predicate on the "failed_reason" field. +func FailedReasonContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldFailedReason, v)) +} + +// FailedReasonHasPrefix applies the HasPrefix predicate on the "failed_reason" field. +func FailedReasonHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldFailedReason, v)) +} + +// FailedReasonHasSuffix applies the HasSuffix predicate on the "failed_reason" field. +func FailedReasonHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldFailedReason, v)) +} + +// FailedReasonIsNil applies the IsNil predicate on the "failed_reason" field. +func FailedReasonIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldFailedReason)) +} + +// FailedReasonNotNil applies the NotNil predicate on the "failed_reason" field. +func FailedReasonNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldFailedReason)) +} + +// FailedReasonEqualFold applies the EqualFold predicate on the "failed_reason" field. +func FailedReasonEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldFailedReason, v)) +} + +// FailedReasonContainsFold applies the ContainsFold predicate on the "failed_reason" field. +func FailedReasonContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldFailedReason, v)) +} + +// ClientIPEQ applies the EQ predicate on the "client_ip" field. +func ClientIPEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldClientIP, v)) +} + +// ClientIPNEQ applies the NEQ predicate on the "client_ip" field. +func ClientIPNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldClientIP, v)) +} + +// ClientIPIn applies the In predicate on the "client_ip" field. +func ClientIPIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldClientIP, vs...)) +} + +// ClientIPNotIn applies the NotIn predicate on the "client_ip" field. +func ClientIPNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldClientIP, vs...)) +} + +// ClientIPGT applies the GT predicate on the "client_ip" field. +func ClientIPGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldClientIP, v)) +} + +// ClientIPGTE applies the GTE predicate on the "client_ip" field. +func ClientIPGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldClientIP, v)) +} + +// ClientIPLT applies the LT predicate on the "client_ip" field. +func ClientIPLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldClientIP, v)) +} + +// ClientIPLTE applies the LTE predicate on the "client_ip" field. +func ClientIPLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldClientIP, v)) +} + +// ClientIPContains applies the Contains predicate on the "client_ip" field. +func ClientIPContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldClientIP, v)) +} + +// ClientIPHasPrefix applies the HasPrefix predicate on the "client_ip" field. +func ClientIPHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldClientIP, v)) +} + +// ClientIPHasSuffix applies the HasSuffix predicate on the "client_ip" field. +func ClientIPHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldClientIP, v)) +} + +// ClientIPEqualFold applies the EqualFold predicate on the "client_ip" field. +func ClientIPEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldClientIP, v)) +} + +// ClientIPContainsFold applies the ContainsFold predicate on the "client_ip" field. +func ClientIPContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldClientIP, v)) +} + +// SrcHostEQ applies the EQ predicate on the "src_host" field. +func SrcHostEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldSrcHost, v)) +} + +// SrcHostNEQ applies the NEQ predicate on the "src_host" field. +func SrcHostNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldSrcHost, v)) +} + +// SrcHostIn applies the In predicate on the "src_host" field. +func SrcHostIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldSrcHost, vs...)) +} + +// SrcHostNotIn applies the NotIn predicate on the "src_host" field. +func SrcHostNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldSrcHost, vs...)) +} + +// SrcHostGT applies the GT predicate on the "src_host" field. +func SrcHostGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldSrcHost, v)) +} + +// SrcHostGTE applies the GTE predicate on the "src_host" field. +func SrcHostGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldSrcHost, v)) +} + +// SrcHostLT applies the LT predicate on the "src_host" field. +func SrcHostLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldSrcHost, v)) +} + +// SrcHostLTE applies the LTE predicate on the "src_host" field. +func SrcHostLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldSrcHost, v)) +} + +// SrcHostContains applies the Contains predicate on the "src_host" field. +func SrcHostContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldSrcHost, v)) +} + +// SrcHostHasPrefix applies the HasPrefix predicate on the "src_host" field. +func SrcHostHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldSrcHost, v)) +} + +// SrcHostHasSuffix applies the HasSuffix predicate on the "src_host" field. +func SrcHostHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldSrcHost, v)) +} + +// SrcHostEqualFold applies the EqualFold predicate on the "src_host" field. +func SrcHostEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldSrcHost, v)) +} + +// SrcHostContainsFold applies the ContainsFold predicate on the "src_host" field. +func SrcHostContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldSrcHost, v)) +} + +// SrcURLEQ applies the EQ predicate on the "src_url" field. +func SrcURLEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldSrcURL, v)) +} + +// SrcURLNEQ applies the NEQ predicate on the "src_url" field. +func SrcURLNEQ(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldSrcURL, v)) +} + +// SrcURLIn applies the In predicate on the "src_url" field. +func SrcURLIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldSrcURL, vs...)) +} + +// SrcURLNotIn applies the NotIn predicate on the "src_url" field. +func SrcURLNotIn(vs ...string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldSrcURL, vs...)) +} + +// SrcURLGT applies the GT predicate on the "src_url" field. +func SrcURLGT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldSrcURL, v)) +} + +// SrcURLGTE applies the GTE predicate on the "src_url" field. +func SrcURLGTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldSrcURL, v)) +} + +// SrcURLLT applies the LT predicate on the "src_url" field. +func SrcURLLT(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldSrcURL, v)) +} + +// SrcURLLTE applies the LTE predicate on the "src_url" field. +func SrcURLLTE(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldSrcURL, v)) +} + +// SrcURLContains applies the Contains predicate on the "src_url" field. +func SrcURLContains(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContains(FieldSrcURL, v)) +} + +// SrcURLHasPrefix applies the HasPrefix predicate on the "src_url" field. +func SrcURLHasPrefix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasPrefix(FieldSrcURL, v)) +} + +// SrcURLHasSuffix applies the HasSuffix predicate on the "src_url" field. +func SrcURLHasSuffix(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldHasSuffix(FieldSrcURL, v)) +} + +// SrcURLIsNil applies the IsNil predicate on the "src_url" field. +func SrcURLIsNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIsNull(FieldSrcURL)) +} + +// SrcURLNotNil applies the NotNil predicate on the "src_url" field. +func SrcURLNotNil() predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotNull(FieldSrcURL)) +} + +// SrcURLEqualFold applies the EqualFold predicate on the "src_url" field. +func SrcURLEqualFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEqualFold(FieldSrcURL, v)) +} + +// SrcURLContainsFold applies the ContainsFold predicate on the "src_url" field. +func SrcURLContainsFold(v string) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldContainsFold(FieldSrcURL, v)) +} + +// CreatedAtEQ applies the EQ predicate on the "created_at" field. +func CreatedAtEQ(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldCreatedAt, v)) +} + +// CreatedAtNEQ applies the NEQ predicate on the "created_at" field. +func CreatedAtNEQ(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldCreatedAt, v)) +} + +// CreatedAtIn applies the In predicate on the "created_at" field. +func CreatedAtIn(vs ...time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldCreatedAt, vs...)) +} + +// CreatedAtNotIn applies the NotIn predicate on the "created_at" field. +func CreatedAtNotIn(vs ...time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldCreatedAt, vs...)) +} + +// CreatedAtGT applies the GT predicate on the "created_at" field. +func CreatedAtGT(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldCreatedAt, v)) +} + +// CreatedAtGTE applies the GTE predicate on the "created_at" field. +func CreatedAtGTE(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldCreatedAt, v)) +} + +// CreatedAtLT applies the LT predicate on the "created_at" field. +func CreatedAtLT(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldCreatedAt, v)) +} + +// CreatedAtLTE applies the LTE predicate on the "created_at" field. +func CreatedAtLTE(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldCreatedAt, v)) +} + +// UpdatedAtEQ applies the EQ predicate on the "updated_at" field. +func UpdatedAtEQ(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field. +func UpdatedAtNEQ(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtIn applies the In predicate on the "updated_at" field. +func UpdatedAtIn(vs ...time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field. +func UpdatedAtNotIn(vs ...time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldNotIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtGT applies the GT predicate on the "updated_at" field. +func UpdatedAtGT(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGT(FieldUpdatedAt, v)) +} + +// UpdatedAtGTE applies the GTE predicate on the "updated_at" field. +func UpdatedAtGTE(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldGTE(FieldUpdatedAt, v)) +} + +// UpdatedAtLT applies the LT predicate on the "updated_at" field. +func UpdatedAtLT(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLT(FieldUpdatedAt, v)) +} + +// UpdatedAtLTE applies the LTE predicate on the "updated_at" field. +func UpdatedAtLTE(v time.Time) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.FieldLTE(FieldUpdatedAt, v)) +} + +// HasUser applies the HasEdge predicate on the "user" edge. +func HasUser() predicate.PaymentOrder { + return predicate.PaymentOrder(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasUserWith applies the HasEdge predicate on the "user" edge with a given conditions (other predicates). +func HasUserWith(preds ...predicate.User) predicate.PaymentOrder { + return predicate.PaymentOrder(func(s *sql.Selector) { + step := newUserStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.PaymentOrder) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.PaymentOrder) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.PaymentOrder) predicate.PaymentOrder { + return predicate.PaymentOrder(sql.NotPredicates(p)) +} diff --git a/backend/ent/paymentorder_create.go b/backend/ent/paymentorder_create.go new file mode 100644 index 0000000000..0fcbf51f56 --- /dev/null +++ b/backend/ent/paymentorder_create.go @@ -0,0 +1,3039 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/paymentorder" + "github.com/Wei-Shaw/sub2api/ent/user" +) + +// PaymentOrderCreate is the builder for creating a PaymentOrder entity. +type PaymentOrderCreate struct { + config + mutation *PaymentOrderMutation + hooks []Hook + conflict []sql.ConflictOption +} + +// SetUserID sets the "user_id" field. +func (_c *PaymentOrderCreate) SetUserID(v int64) *PaymentOrderCreate { + _c.mutation.SetUserID(v) + return _c +} + +// SetUserEmail sets the "user_email" field. +func (_c *PaymentOrderCreate) SetUserEmail(v string) *PaymentOrderCreate { + _c.mutation.SetUserEmail(v) + return _c +} + +// SetUserName sets the "user_name" field. +func (_c *PaymentOrderCreate) SetUserName(v string) *PaymentOrderCreate { + _c.mutation.SetUserName(v) + return _c +} + +// SetUserNotes sets the "user_notes" field. +func (_c *PaymentOrderCreate) SetUserNotes(v string) *PaymentOrderCreate { + _c.mutation.SetUserNotes(v) + return _c +} + +// SetNillableUserNotes sets the "user_notes" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableUserNotes(v *string) *PaymentOrderCreate { + if v != nil { + _c.SetUserNotes(*v) + } + return _c +} + +// SetAmount sets the "amount" field. +func (_c *PaymentOrderCreate) SetAmount(v float64) *PaymentOrderCreate { + _c.mutation.SetAmount(v) + return _c +} + +// SetPayAmount sets the "pay_amount" field. +func (_c *PaymentOrderCreate) SetPayAmount(v float64) *PaymentOrderCreate { + _c.mutation.SetPayAmount(v) + return _c +} + +// SetFeeRate sets the "fee_rate" field. +func (_c *PaymentOrderCreate) SetFeeRate(v float64) *PaymentOrderCreate { + _c.mutation.SetFeeRate(v) + return _c +} + +// SetNillableFeeRate sets the "fee_rate" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableFeeRate(v *float64) *PaymentOrderCreate { + if v != nil { + _c.SetFeeRate(*v) + } + return _c +} + +// SetRechargeCode sets the "recharge_code" field. +func (_c *PaymentOrderCreate) SetRechargeCode(v string) *PaymentOrderCreate { + _c.mutation.SetRechargeCode(v) + return _c +} + +// SetPaymentType sets the "payment_type" field. +func (_c *PaymentOrderCreate) SetPaymentType(v string) *PaymentOrderCreate { + _c.mutation.SetPaymentType(v) + return _c +} + +// SetPaymentTradeNo sets the "payment_trade_no" field. +func (_c *PaymentOrderCreate) SetPaymentTradeNo(v string) *PaymentOrderCreate { + _c.mutation.SetPaymentTradeNo(v) + return _c +} + +// SetPayURL sets the "pay_url" field. +func (_c *PaymentOrderCreate) SetPayURL(v string) *PaymentOrderCreate { + _c.mutation.SetPayURL(v) + return _c +} + +// SetNillablePayURL sets the "pay_url" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillablePayURL(v *string) *PaymentOrderCreate { + if v != nil { + _c.SetPayURL(*v) + } + return _c +} + +// SetQrCode sets the "qr_code" field. +func (_c *PaymentOrderCreate) SetQrCode(v string) *PaymentOrderCreate { + _c.mutation.SetQrCode(v) + return _c +} + +// SetNillableQrCode sets the "qr_code" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableQrCode(v *string) *PaymentOrderCreate { + if v != nil { + _c.SetQrCode(*v) + } + return _c +} + +// SetQrCodeImg sets the "qr_code_img" field. +func (_c *PaymentOrderCreate) SetQrCodeImg(v string) *PaymentOrderCreate { + _c.mutation.SetQrCodeImg(v) + return _c +} + +// SetNillableQrCodeImg sets the "qr_code_img" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableQrCodeImg(v *string) *PaymentOrderCreate { + if v != nil { + _c.SetQrCodeImg(*v) + } + return _c +} + +// SetOrderType sets the "order_type" field. +func (_c *PaymentOrderCreate) SetOrderType(v string) *PaymentOrderCreate { + _c.mutation.SetOrderType(v) + return _c +} + +// SetNillableOrderType sets the "order_type" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableOrderType(v *string) *PaymentOrderCreate { + if v != nil { + _c.SetOrderType(*v) + } + return _c +} + +// SetPlanID sets the "plan_id" field. +func (_c *PaymentOrderCreate) SetPlanID(v int64) *PaymentOrderCreate { + _c.mutation.SetPlanID(v) + return _c +} + +// SetNillablePlanID sets the "plan_id" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillablePlanID(v *int64) *PaymentOrderCreate { + if v != nil { + _c.SetPlanID(*v) + } + return _c +} + +// SetSubscriptionGroupID sets the "subscription_group_id" field. +func (_c *PaymentOrderCreate) SetSubscriptionGroupID(v int64) *PaymentOrderCreate { + _c.mutation.SetSubscriptionGroupID(v) + return _c +} + +// SetNillableSubscriptionGroupID sets the "subscription_group_id" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableSubscriptionGroupID(v *int64) *PaymentOrderCreate { + if v != nil { + _c.SetSubscriptionGroupID(*v) + } + return _c +} + +// SetSubscriptionDays sets the "subscription_days" field. +func (_c *PaymentOrderCreate) SetSubscriptionDays(v int) *PaymentOrderCreate { + _c.mutation.SetSubscriptionDays(v) + return _c +} + +// SetNillableSubscriptionDays sets the "subscription_days" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableSubscriptionDays(v *int) *PaymentOrderCreate { + if v != nil { + _c.SetSubscriptionDays(*v) + } + return _c +} + +// SetProviderInstanceID sets the "provider_instance_id" field. +func (_c *PaymentOrderCreate) SetProviderInstanceID(v string) *PaymentOrderCreate { + _c.mutation.SetProviderInstanceID(v) + return _c +} + +// SetNillableProviderInstanceID sets the "provider_instance_id" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableProviderInstanceID(v *string) *PaymentOrderCreate { + if v != nil { + _c.SetProviderInstanceID(*v) + } + return _c +} + +// SetStatus sets the "status" field. +func (_c *PaymentOrderCreate) SetStatus(v string) *PaymentOrderCreate { + _c.mutation.SetStatus(v) + return _c +} + +// SetNillableStatus sets the "status" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableStatus(v *string) *PaymentOrderCreate { + if v != nil { + _c.SetStatus(*v) + } + return _c +} + +// SetRefundAmount sets the "refund_amount" field. +func (_c *PaymentOrderCreate) SetRefundAmount(v float64) *PaymentOrderCreate { + _c.mutation.SetRefundAmount(v) + return _c +} + +// SetNillableRefundAmount sets the "refund_amount" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableRefundAmount(v *float64) *PaymentOrderCreate { + if v != nil { + _c.SetRefundAmount(*v) + } + return _c +} + +// SetRefundReason sets the "refund_reason" field. +func (_c *PaymentOrderCreate) SetRefundReason(v string) *PaymentOrderCreate { + _c.mutation.SetRefundReason(v) + return _c +} + +// SetNillableRefundReason sets the "refund_reason" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableRefundReason(v *string) *PaymentOrderCreate { + if v != nil { + _c.SetRefundReason(*v) + } + return _c +} + +// SetRefundAt sets the "refund_at" field. +func (_c *PaymentOrderCreate) SetRefundAt(v time.Time) *PaymentOrderCreate { + _c.mutation.SetRefundAt(v) + return _c +} + +// SetNillableRefundAt sets the "refund_at" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableRefundAt(v *time.Time) *PaymentOrderCreate { + if v != nil { + _c.SetRefundAt(*v) + } + return _c +} + +// SetForceRefund sets the "force_refund" field. +func (_c *PaymentOrderCreate) SetForceRefund(v bool) *PaymentOrderCreate { + _c.mutation.SetForceRefund(v) + return _c +} + +// SetNillableForceRefund sets the "force_refund" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableForceRefund(v *bool) *PaymentOrderCreate { + if v != nil { + _c.SetForceRefund(*v) + } + return _c +} + +// SetRefundRequestedAt sets the "refund_requested_at" field. +func (_c *PaymentOrderCreate) SetRefundRequestedAt(v time.Time) *PaymentOrderCreate { + _c.mutation.SetRefundRequestedAt(v) + return _c +} + +// SetNillableRefundRequestedAt sets the "refund_requested_at" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableRefundRequestedAt(v *time.Time) *PaymentOrderCreate { + if v != nil { + _c.SetRefundRequestedAt(*v) + } + return _c +} + +// SetRefundRequestReason sets the "refund_request_reason" field. +func (_c *PaymentOrderCreate) SetRefundRequestReason(v string) *PaymentOrderCreate { + _c.mutation.SetRefundRequestReason(v) + return _c +} + +// SetNillableRefundRequestReason sets the "refund_request_reason" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableRefundRequestReason(v *string) *PaymentOrderCreate { + if v != nil { + _c.SetRefundRequestReason(*v) + } + return _c +} + +// SetRefundRequestedBy sets the "refund_requested_by" field. +func (_c *PaymentOrderCreate) SetRefundRequestedBy(v string) *PaymentOrderCreate { + _c.mutation.SetRefundRequestedBy(v) + return _c +} + +// SetNillableRefundRequestedBy sets the "refund_requested_by" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableRefundRequestedBy(v *string) *PaymentOrderCreate { + if v != nil { + _c.SetRefundRequestedBy(*v) + } + return _c +} + +// SetExpiresAt sets the "expires_at" field. +func (_c *PaymentOrderCreate) SetExpiresAt(v time.Time) *PaymentOrderCreate { + _c.mutation.SetExpiresAt(v) + return _c +} + +// SetPaidAt sets the "paid_at" field. +func (_c *PaymentOrderCreate) SetPaidAt(v time.Time) *PaymentOrderCreate { + _c.mutation.SetPaidAt(v) + return _c +} + +// SetNillablePaidAt sets the "paid_at" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillablePaidAt(v *time.Time) *PaymentOrderCreate { + if v != nil { + _c.SetPaidAt(*v) + } + return _c +} + +// SetCompletedAt sets the "completed_at" field. +func (_c *PaymentOrderCreate) SetCompletedAt(v time.Time) *PaymentOrderCreate { + _c.mutation.SetCompletedAt(v) + return _c +} + +// SetNillableCompletedAt sets the "completed_at" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableCompletedAt(v *time.Time) *PaymentOrderCreate { + if v != nil { + _c.SetCompletedAt(*v) + } + return _c +} + +// SetFailedAt sets the "failed_at" field. +func (_c *PaymentOrderCreate) SetFailedAt(v time.Time) *PaymentOrderCreate { + _c.mutation.SetFailedAt(v) + return _c +} + +// SetNillableFailedAt sets the "failed_at" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableFailedAt(v *time.Time) *PaymentOrderCreate { + if v != nil { + _c.SetFailedAt(*v) + } + return _c +} + +// SetFailedReason sets the "failed_reason" field. +func (_c *PaymentOrderCreate) SetFailedReason(v string) *PaymentOrderCreate { + _c.mutation.SetFailedReason(v) + return _c +} + +// SetNillableFailedReason sets the "failed_reason" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableFailedReason(v *string) *PaymentOrderCreate { + if v != nil { + _c.SetFailedReason(*v) + } + return _c +} + +// SetClientIP sets the "client_ip" field. +func (_c *PaymentOrderCreate) SetClientIP(v string) *PaymentOrderCreate { + _c.mutation.SetClientIP(v) + return _c +} + +// SetSrcHost sets the "src_host" field. +func (_c *PaymentOrderCreate) SetSrcHost(v string) *PaymentOrderCreate { + _c.mutation.SetSrcHost(v) + return _c +} + +// SetSrcURL sets the "src_url" field. +func (_c *PaymentOrderCreate) SetSrcURL(v string) *PaymentOrderCreate { + _c.mutation.SetSrcURL(v) + return _c +} + +// SetNillableSrcURL sets the "src_url" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableSrcURL(v *string) *PaymentOrderCreate { + if v != nil { + _c.SetSrcURL(*v) + } + return _c +} + +// SetCreatedAt sets the "created_at" field. +func (_c *PaymentOrderCreate) SetCreatedAt(v time.Time) *PaymentOrderCreate { + _c.mutation.SetCreatedAt(v) + return _c +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableCreatedAt(v *time.Time) *PaymentOrderCreate { + if v != nil { + _c.SetCreatedAt(*v) + } + return _c +} + +// SetUpdatedAt sets the "updated_at" field. +func (_c *PaymentOrderCreate) SetUpdatedAt(v time.Time) *PaymentOrderCreate { + _c.mutation.SetUpdatedAt(v) + return _c +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (_c *PaymentOrderCreate) SetNillableUpdatedAt(v *time.Time) *PaymentOrderCreate { + if v != nil { + _c.SetUpdatedAt(*v) + } + return _c +} + +// SetUser sets the "user" edge to the User entity. +func (_c *PaymentOrderCreate) SetUser(v *User) *PaymentOrderCreate { + return _c.SetUserID(v.ID) +} + +// Mutation returns the PaymentOrderMutation object of the builder. +func (_c *PaymentOrderCreate) Mutation() *PaymentOrderMutation { + return _c.mutation +} + +// Save creates the PaymentOrder in the database. +func (_c *PaymentOrderCreate) Save(ctx context.Context) (*PaymentOrder, error) { + _c.defaults() + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (_c *PaymentOrderCreate) SaveX(ctx context.Context) *PaymentOrder { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *PaymentOrderCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *PaymentOrderCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_c *PaymentOrderCreate) defaults() { + if _, ok := _c.mutation.FeeRate(); !ok { + v := paymentorder.DefaultFeeRate + _c.mutation.SetFeeRate(v) + } + if _, ok := _c.mutation.OrderType(); !ok { + v := paymentorder.DefaultOrderType + _c.mutation.SetOrderType(v) + } + if _, ok := _c.mutation.Status(); !ok { + v := paymentorder.DefaultStatus + _c.mutation.SetStatus(v) + } + if _, ok := _c.mutation.RefundAmount(); !ok { + v := paymentorder.DefaultRefundAmount + _c.mutation.SetRefundAmount(v) + } + if _, ok := _c.mutation.ForceRefund(); !ok { + v := paymentorder.DefaultForceRefund + _c.mutation.SetForceRefund(v) + } + if _, ok := _c.mutation.CreatedAt(); !ok { + v := paymentorder.DefaultCreatedAt() + _c.mutation.SetCreatedAt(v) + } + if _, ok := _c.mutation.UpdatedAt(); !ok { + v := paymentorder.DefaultUpdatedAt() + _c.mutation.SetUpdatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_c *PaymentOrderCreate) check() error { + if _, ok := _c.mutation.UserID(); !ok { + return &ValidationError{Name: "user_id", err: errors.New(`ent: missing required field "PaymentOrder.user_id"`)} + } + if _, ok := _c.mutation.UserEmail(); !ok { + return &ValidationError{Name: "user_email", err: errors.New(`ent: missing required field "PaymentOrder.user_email"`)} + } + if v, ok := _c.mutation.UserEmail(); ok { + if err := paymentorder.UserEmailValidator(v); err != nil { + return &ValidationError{Name: "user_email", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.user_email": %w`, err)} + } + } + if _, ok := _c.mutation.UserName(); !ok { + return &ValidationError{Name: "user_name", err: errors.New(`ent: missing required field "PaymentOrder.user_name"`)} + } + if v, ok := _c.mutation.UserName(); ok { + if err := paymentorder.UserNameValidator(v); err != nil { + return &ValidationError{Name: "user_name", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.user_name": %w`, err)} + } + } + if _, ok := _c.mutation.Amount(); !ok { + return &ValidationError{Name: "amount", err: errors.New(`ent: missing required field "PaymentOrder.amount"`)} + } + if _, ok := _c.mutation.PayAmount(); !ok { + return &ValidationError{Name: "pay_amount", err: errors.New(`ent: missing required field "PaymentOrder.pay_amount"`)} + } + if _, ok := _c.mutation.FeeRate(); !ok { + return &ValidationError{Name: "fee_rate", err: errors.New(`ent: missing required field "PaymentOrder.fee_rate"`)} + } + if _, ok := _c.mutation.RechargeCode(); !ok { + return &ValidationError{Name: "recharge_code", err: errors.New(`ent: missing required field "PaymentOrder.recharge_code"`)} + } + if v, ok := _c.mutation.RechargeCode(); ok { + if err := paymentorder.RechargeCodeValidator(v); err != nil { + return &ValidationError{Name: "recharge_code", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.recharge_code": %w`, err)} + } + } + if _, ok := _c.mutation.PaymentType(); !ok { + return &ValidationError{Name: "payment_type", err: errors.New(`ent: missing required field "PaymentOrder.payment_type"`)} + } + if v, ok := _c.mutation.PaymentType(); ok { + if err := paymentorder.PaymentTypeValidator(v); err != nil { + return &ValidationError{Name: "payment_type", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.payment_type": %w`, err)} + } + } + if _, ok := _c.mutation.PaymentTradeNo(); !ok { + return &ValidationError{Name: "payment_trade_no", err: errors.New(`ent: missing required field "PaymentOrder.payment_trade_no"`)} + } + if v, ok := _c.mutation.PaymentTradeNo(); ok { + if err := paymentorder.PaymentTradeNoValidator(v); err != nil { + return &ValidationError{Name: "payment_trade_no", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.payment_trade_no": %w`, err)} + } + } + if _, ok := _c.mutation.OrderType(); !ok { + return &ValidationError{Name: "order_type", err: errors.New(`ent: missing required field "PaymentOrder.order_type"`)} + } + if v, ok := _c.mutation.OrderType(); ok { + if err := paymentorder.OrderTypeValidator(v); err != nil { + return &ValidationError{Name: "order_type", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.order_type": %w`, err)} + } + } + if v, ok := _c.mutation.ProviderInstanceID(); ok { + if err := paymentorder.ProviderInstanceIDValidator(v); err != nil { + return &ValidationError{Name: "provider_instance_id", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.provider_instance_id": %w`, err)} + } + } + if _, ok := _c.mutation.Status(); !ok { + return &ValidationError{Name: "status", err: errors.New(`ent: missing required field "PaymentOrder.status"`)} + } + if v, ok := _c.mutation.Status(); ok { + if err := paymentorder.StatusValidator(v); err != nil { + return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.status": %w`, err)} + } + } + if _, ok := _c.mutation.RefundAmount(); !ok { + return &ValidationError{Name: "refund_amount", err: errors.New(`ent: missing required field "PaymentOrder.refund_amount"`)} + } + if _, ok := _c.mutation.ForceRefund(); !ok { + return &ValidationError{Name: "force_refund", err: errors.New(`ent: missing required field "PaymentOrder.force_refund"`)} + } + if v, ok := _c.mutation.RefundRequestedBy(); ok { + if err := paymentorder.RefundRequestedByValidator(v); err != nil { + return &ValidationError{Name: "refund_requested_by", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.refund_requested_by": %w`, err)} + } + } + if _, ok := _c.mutation.ExpiresAt(); !ok { + return &ValidationError{Name: "expires_at", err: errors.New(`ent: missing required field "PaymentOrder.expires_at"`)} + } + if _, ok := _c.mutation.ClientIP(); !ok { + return &ValidationError{Name: "client_ip", err: errors.New(`ent: missing required field "PaymentOrder.client_ip"`)} + } + if v, ok := _c.mutation.ClientIP(); ok { + if err := paymentorder.ClientIPValidator(v); err != nil { + return &ValidationError{Name: "client_ip", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.client_ip": %w`, err)} + } + } + if _, ok := _c.mutation.SrcHost(); !ok { + return &ValidationError{Name: "src_host", err: errors.New(`ent: missing required field "PaymentOrder.src_host"`)} + } + if v, ok := _c.mutation.SrcHost(); ok { + if err := paymentorder.SrcHostValidator(v); err != nil { + return &ValidationError{Name: "src_host", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.src_host": %w`, err)} + } + } + if _, ok := _c.mutation.CreatedAt(); !ok { + return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "PaymentOrder.created_at"`)} + } + if _, ok := _c.mutation.UpdatedAt(); !ok { + return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "PaymentOrder.updated_at"`)} + } + if len(_c.mutation.UserIDs()) == 0 { + return &ValidationError{Name: "user", err: errors.New(`ent: missing required edge "PaymentOrder.user"`)} + } + return nil +} + +func (_c *PaymentOrderCreate) sqlSave(ctx context.Context) (*PaymentOrder, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + id := _spec.ID.Value.(int64) + _node.ID = int64(id) + _c.mutation.id = &_node.ID + _c.mutation.done = true + return _node, nil +} + +func (_c *PaymentOrderCreate) createSpec() (*PaymentOrder, *sqlgraph.CreateSpec) { + var ( + _node = &PaymentOrder{config: _c.config} + _spec = sqlgraph.NewCreateSpec(paymentorder.Table, sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64)) + ) + _spec.OnConflict = _c.conflict + if value, ok := _c.mutation.UserEmail(); ok { + _spec.SetField(paymentorder.FieldUserEmail, field.TypeString, value) + _node.UserEmail = value + } + if value, ok := _c.mutation.UserName(); ok { + _spec.SetField(paymentorder.FieldUserName, field.TypeString, value) + _node.UserName = value + } + if value, ok := _c.mutation.UserNotes(); ok { + _spec.SetField(paymentorder.FieldUserNotes, field.TypeString, value) + _node.UserNotes = &value + } + if value, ok := _c.mutation.Amount(); ok { + _spec.SetField(paymentorder.FieldAmount, field.TypeFloat64, value) + _node.Amount = value + } + if value, ok := _c.mutation.PayAmount(); ok { + _spec.SetField(paymentorder.FieldPayAmount, field.TypeFloat64, value) + _node.PayAmount = value + } + if value, ok := _c.mutation.FeeRate(); ok { + _spec.SetField(paymentorder.FieldFeeRate, field.TypeFloat64, value) + _node.FeeRate = value + } + if value, ok := _c.mutation.RechargeCode(); ok { + _spec.SetField(paymentorder.FieldRechargeCode, field.TypeString, value) + _node.RechargeCode = value + } + if value, ok := _c.mutation.PaymentType(); ok { + _spec.SetField(paymentorder.FieldPaymentType, field.TypeString, value) + _node.PaymentType = value + } + if value, ok := _c.mutation.PaymentTradeNo(); ok { + _spec.SetField(paymentorder.FieldPaymentTradeNo, field.TypeString, value) + _node.PaymentTradeNo = value + } + if value, ok := _c.mutation.PayURL(); ok { + _spec.SetField(paymentorder.FieldPayURL, field.TypeString, value) + _node.PayURL = &value + } + if value, ok := _c.mutation.QrCode(); ok { + _spec.SetField(paymentorder.FieldQrCode, field.TypeString, value) + _node.QrCode = &value + } + if value, ok := _c.mutation.QrCodeImg(); ok { + _spec.SetField(paymentorder.FieldQrCodeImg, field.TypeString, value) + _node.QrCodeImg = &value + } + if value, ok := _c.mutation.OrderType(); ok { + _spec.SetField(paymentorder.FieldOrderType, field.TypeString, value) + _node.OrderType = value + } + if value, ok := _c.mutation.PlanID(); ok { + _spec.SetField(paymentorder.FieldPlanID, field.TypeInt64, value) + _node.PlanID = &value + } + if value, ok := _c.mutation.SubscriptionGroupID(); ok { + _spec.SetField(paymentorder.FieldSubscriptionGroupID, field.TypeInt64, value) + _node.SubscriptionGroupID = &value + } + if value, ok := _c.mutation.SubscriptionDays(); ok { + _spec.SetField(paymentorder.FieldSubscriptionDays, field.TypeInt, value) + _node.SubscriptionDays = &value + } + if value, ok := _c.mutation.ProviderInstanceID(); ok { + _spec.SetField(paymentorder.FieldProviderInstanceID, field.TypeString, value) + _node.ProviderInstanceID = &value + } + if value, ok := _c.mutation.Status(); ok { + _spec.SetField(paymentorder.FieldStatus, field.TypeString, value) + _node.Status = value + } + if value, ok := _c.mutation.RefundAmount(); ok { + _spec.SetField(paymentorder.FieldRefundAmount, field.TypeFloat64, value) + _node.RefundAmount = value + } + if value, ok := _c.mutation.RefundReason(); ok { + _spec.SetField(paymentorder.FieldRefundReason, field.TypeString, value) + _node.RefundReason = &value + } + if value, ok := _c.mutation.RefundAt(); ok { + _spec.SetField(paymentorder.FieldRefundAt, field.TypeTime, value) + _node.RefundAt = &value + } + if value, ok := _c.mutation.ForceRefund(); ok { + _spec.SetField(paymentorder.FieldForceRefund, field.TypeBool, value) + _node.ForceRefund = value + } + if value, ok := _c.mutation.RefundRequestedAt(); ok { + _spec.SetField(paymentorder.FieldRefundRequestedAt, field.TypeTime, value) + _node.RefundRequestedAt = &value + } + if value, ok := _c.mutation.RefundRequestReason(); ok { + _spec.SetField(paymentorder.FieldRefundRequestReason, field.TypeString, value) + _node.RefundRequestReason = &value + } + if value, ok := _c.mutation.RefundRequestedBy(); ok { + _spec.SetField(paymentorder.FieldRefundRequestedBy, field.TypeString, value) + _node.RefundRequestedBy = &value + } + if value, ok := _c.mutation.ExpiresAt(); ok { + _spec.SetField(paymentorder.FieldExpiresAt, field.TypeTime, value) + _node.ExpiresAt = value + } + if value, ok := _c.mutation.PaidAt(); ok { + _spec.SetField(paymentorder.FieldPaidAt, field.TypeTime, value) + _node.PaidAt = &value + } + if value, ok := _c.mutation.CompletedAt(); ok { + _spec.SetField(paymentorder.FieldCompletedAt, field.TypeTime, value) + _node.CompletedAt = &value + } + if value, ok := _c.mutation.FailedAt(); ok { + _spec.SetField(paymentorder.FieldFailedAt, field.TypeTime, value) + _node.FailedAt = &value + } + if value, ok := _c.mutation.FailedReason(); ok { + _spec.SetField(paymentorder.FieldFailedReason, field.TypeString, value) + _node.FailedReason = &value + } + if value, ok := _c.mutation.ClientIP(); ok { + _spec.SetField(paymentorder.FieldClientIP, field.TypeString, value) + _node.ClientIP = value + } + if value, ok := _c.mutation.SrcHost(); ok { + _spec.SetField(paymentorder.FieldSrcHost, field.TypeString, value) + _node.SrcHost = value + } + if value, ok := _c.mutation.SrcURL(); ok { + _spec.SetField(paymentorder.FieldSrcURL, field.TypeString, value) + _node.SrcURL = &value + } + if value, ok := _c.mutation.CreatedAt(); ok { + _spec.SetField(paymentorder.FieldCreatedAt, field.TypeTime, value) + _node.CreatedAt = value + } + if value, ok := _c.mutation.UpdatedAt(); ok { + _spec.SetField(paymentorder.FieldUpdatedAt, field.TypeTime, value) + _node.UpdatedAt = value + } + if nodes := _c.mutation.UserIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: paymentorder.UserTable, + Columns: []string{paymentorder.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.UserID = nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause +// of the `INSERT` statement. For example: +// +// client.PaymentOrder.Create(). +// SetUserID(v). +// OnConflict( +// // Update the row with the new values +// // the was proposed for insertion. +// sql.ResolveWithNewValues(), +// ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.PaymentOrderUpsert) { +// SetUserID(v+v). +// }). +// Exec(ctx) +func (_c *PaymentOrderCreate) OnConflict(opts ...sql.ConflictOption) *PaymentOrderUpsertOne { + _c.conflict = opts + return &PaymentOrderUpsertOne{ + create: _c, + } +} + +// OnConflictColumns calls `OnConflict` and configures the columns +// as conflict target. Using this option is equivalent to using: +// +// client.PaymentOrder.Create(). +// OnConflict(sql.ConflictColumns(columns...)). +// Exec(ctx) +func (_c *PaymentOrderCreate) OnConflictColumns(columns ...string) *PaymentOrderUpsertOne { + _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) + return &PaymentOrderUpsertOne{ + create: _c, + } +} + +type ( + // PaymentOrderUpsertOne is the builder for "upsert"-ing + // one PaymentOrder node. + PaymentOrderUpsertOne struct { + create *PaymentOrderCreate + } + + // PaymentOrderUpsert is the "OnConflict" setter. + PaymentOrderUpsert struct { + *sql.UpdateSet + } +) + +// SetUserID sets the "user_id" field. +func (u *PaymentOrderUpsert) SetUserID(v int64) *PaymentOrderUpsert { + u.Set(paymentorder.FieldUserID, v) + return u +} + +// UpdateUserID sets the "user_id" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateUserID() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldUserID) + return u +} + +// SetUserEmail sets the "user_email" field. +func (u *PaymentOrderUpsert) SetUserEmail(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldUserEmail, v) + return u +} + +// UpdateUserEmail sets the "user_email" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateUserEmail() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldUserEmail) + return u +} + +// SetUserName sets the "user_name" field. +func (u *PaymentOrderUpsert) SetUserName(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldUserName, v) + return u +} + +// UpdateUserName sets the "user_name" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateUserName() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldUserName) + return u +} + +// SetUserNotes sets the "user_notes" field. +func (u *PaymentOrderUpsert) SetUserNotes(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldUserNotes, v) + return u +} + +// UpdateUserNotes sets the "user_notes" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateUserNotes() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldUserNotes) + return u +} + +// ClearUserNotes clears the value of the "user_notes" field. +func (u *PaymentOrderUpsert) ClearUserNotes() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldUserNotes) + return u +} + +// SetAmount sets the "amount" field. +func (u *PaymentOrderUpsert) SetAmount(v float64) *PaymentOrderUpsert { + u.Set(paymentorder.FieldAmount, v) + return u +} + +// UpdateAmount sets the "amount" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateAmount() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldAmount) + return u +} + +// AddAmount adds v to the "amount" field. +func (u *PaymentOrderUpsert) AddAmount(v float64) *PaymentOrderUpsert { + u.Add(paymentorder.FieldAmount, v) + return u +} + +// SetPayAmount sets the "pay_amount" field. +func (u *PaymentOrderUpsert) SetPayAmount(v float64) *PaymentOrderUpsert { + u.Set(paymentorder.FieldPayAmount, v) + return u +} + +// UpdatePayAmount sets the "pay_amount" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdatePayAmount() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldPayAmount) + return u +} + +// AddPayAmount adds v to the "pay_amount" field. +func (u *PaymentOrderUpsert) AddPayAmount(v float64) *PaymentOrderUpsert { + u.Add(paymentorder.FieldPayAmount, v) + return u +} + +// SetFeeRate sets the "fee_rate" field. +func (u *PaymentOrderUpsert) SetFeeRate(v float64) *PaymentOrderUpsert { + u.Set(paymentorder.FieldFeeRate, v) + return u +} + +// UpdateFeeRate sets the "fee_rate" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateFeeRate() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldFeeRate) + return u +} + +// AddFeeRate adds v to the "fee_rate" field. +func (u *PaymentOrderUpsert) AddFeeRate(v float64) *PaymentOrderUpsert { + u.Add(paymentorder.FieldFeeRate, v) + return u +} + +// SetRechargeCode sets the "recharge_code" field. +func (u *PaymentOrderUpsert) SetRechargeCode(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldRechargeCode, v) + return u +} + +// UpdateRechargeCode sets the "recharge_code" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateRechargeCode() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldRechargeCode) + return u +} + +// SetPaymentType sets the "payment_type" field. +func (u *PaymentOrderUpsert) SetPaymentType(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldPaymentType, v) + return u +} + +// UpdatePaymentType sets the "payment_type" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdatePaymentType() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldPaymentType) + return u +} + +// SetPaymentTradeNo sets the "payment_trade_no" field. +func (u *PaymentOrderUpsert) SetPaymentTradeNo(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldPaymentTradeNo, v) + return u +} + +// UpdatePaymentTradeNo sets the "payment_trade_no" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdatePaymentTradeNo() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldPaymentTradeNo) + return u +} + +// SetPayURL sets the "pay_url" field. +func (u *PaymentOrderUpsert) SetPayURL(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldPayURL, v) + return u +} + +// UpdatePayURL sets the "pay_url" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdatePayURL() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldPayURL) + return u +} + +// ClearPayURL clears the value of the "pay_url" field. +func (u *PaymentOrderUpsert) ClearPayURL() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldPayURL) + return u +} + +// SetQrCode sets the "qr_code" field. +func (u *PaymentOrderUpsert) SetQrCode(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldQrCode, v) + return u +} + +// UpdateQrCode sets the "qr_code" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateQrCode() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldQrCode) + return u +} + +// ClearQrCode clears the value of the "qr_code" field. +func (u *PaymentOrderUpsert) ClearQrCode() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldQrCode) + return u +} + +// SetQrCodeImg sets the "qr_code_img" field. +func (u *PaymentOrderUpsert) SetQrCodeImg(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldQrCodeImg, v) + return u +} + +// UpdateQrCodeImg sets the "qr_code_img" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateQrCodeImg() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldQrCodeImg) + return u +} + +// ClearQrCodeImg clears the value of the "qr_code_img" field. +func (u *PaymentOrderUpsert) ClearQrCodeImg() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldQrCodeImg) + return u +} + +// SetOrderType sets the "order_type" field. +func (u *PaymentOrderUpsert) SetOrderType(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldOrderType, v) + return u +} + +// UpdateOrderType sets the "order_type" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateOrderType() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldOrderType) + return u +} + +// SetPlanID sets the "plan_id" field. +func (u *PaymentOrderUpsert) SetPlanID(v int64) *PaymentOrderUpsert { + u.Set(paymentorder.FieldPlanID, v) + return u +} + +// UpdatePlanID sets the "plan_id" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdatePlanID() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldPlanID) + return u +} + +// AddPlanID adds v to the "plan_id" field. +func (u *PaymentOrderUpsert) AddPlanID(v int64) *PaymentOrderUpsert { + u.Add(paymentorder.FieldPlanID, v) + return u +} + +// ClearPlanID clears the value of the "plan_id" field. +func (u *PaymentOrderUpsert) ClearPlanID() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldPlanID) + return u +} + +// SetSubscriptionGroupID sets the "subscription_group_id" field. +func (u *PaymentOrderUpsert) SetSubscriptionGroupID(v int64) *PaymentOrderUpsert { + u.Set(paymentorder.FieldSubscriptionGroupID, v) + return u +} + +// UpdateSubscriptionGroupID sets the "subscription_group_id" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateSubscriptionGroupID() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldSubscriptionGroupID) + return u +} + +// AddSubscriptionGroupID adds v to the "subscription_group_id" field. +func (u *PaymentOrderUpsert) AddSubscriptionGroupID(v int64) *PaymentOrderUpsert { + u.Add(paymentorder.FieldSubscriptionGroupID, v) + return u +} + +// ClearSubscriptionGroupID clears the value of the "subscription_group_id" field. +func (u *PaymentOrderUpsert) ClearSubscriptionGroupID() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldSubscriptionGroupID) + return u +} + +// SetSubscriptionDays sets the "subscription_days" field. +func (u *PaymentOrderUpsert) SetSubscriptionDays(v int) *PaymentOrderUpsert { + u.Set(paymentorder.FieldSubscriptionDays, v) + return u +} + +// UpdateSubscriptionDays sets the "subscription_days" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateSubscriptionDays() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldSubscriptionDays) + return u +} + +// AddSubscriptionDays adds v to the "subscription_days" field. +func (u *PaymentOrderUpsert) AddSubscriptionDays(v int) *PaymentOrderUpsert { + u.Add(paymentorder.FieldSubscriptionDays, v) + return u +} + +// ClearSubscriptionDays clears the value of the "subscription_days" field. +func (u *PaymentOrderUpsert) ClearSubscriptionDays() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldSubscriptionDays) + return u +} + +// SetProviderInstanceID sets the "provider_instance_id" field. +func (u *PaymentOrderUpsert) SetProviderInstanceID(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldProviderInstanceID, v) + return u +} + +// UpdateProviderInstanceID sets the "provider_instance_id" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateProviderInstanceID() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldProviderInstanceID) + return u +} + +// ClearProviderInstanceID clears the value of the "provider_instance_id" field. +func (u *PaymentOrderUpsert) ClearProviderInstanceID() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldProviderInstanceID) + return u +} + +// SetStatus sets the "status" field. +func (u *PaymentOrderUpsert) SetStatus(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldStatus, v) + return u +} + +// UpdateStatus sets the "status" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateStatus() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldStatus) + return u +} + +// SetRefundAmount sets the "refund_amount" field. +func (u *PaymentOrderUpsert) SetRefundAmount(v float64) *PaymentOrderUpsert { + u.Set(paymentorder.FieldRefundAmount, v) + return u +} + +// UpdateRefundAmount sets the "refund_amount" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateRefundAmount() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldRefundAmount) + return u +} + +// AddRefundAmount adds v to the "refund_amount" field. +func (u *PaymentOrderUpsert) AddRefundAmount(v float64) *PaymentOrderUpsert { + u.Add(paymentorder.FieldRefundAmount, v) + return u +} + +// SetRefundReason sets the "refund_reason" field. +func (u *PaymentOrderUpsert) SetRefundReason(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldRefundReason, v) + return u +} + +// UpdateRefundReason sets the "refund_reason" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateRefundReason() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldRefundReason) + return u +} + +// ClearRefundReason clears the value of the "refund_reason" field. +func (u *PaymentOrderUpsert) ClearRefundReason() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldRefundReason) + return u +} + +// SetRefundAt sets the "refund_at" field. +func (u *PaymentOrderUpsert) SetRefundAt(v time.Time) *PaymentOrderUpsert { + u.Set(paymentorder.FieldRefundAt, v) + return u +} + +// UpdateRefundAt sets the "refund_at" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateRefundAt() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldRefundAt) + return u +} + +// ClearRefundAt clears the value of the "refund_at" field. +func (u *PaymentOrderUpsert) ClearRefundAt() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldRefundAt) + return u +} + +// SetForceRefund sets the "force_refund" field. +func (u *PaymentOrderUpsert) SetForceRefund(v bool) *PaymentOrderUpsert { + u.Set(paymentorder.FieldForceRefund, v) + return u +} + +// UpdateForceRefund sets the "force_refund" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateForceRefund() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldForceRefund) + return u +} + +// SetRefundRequestedAt sets the "refund_requested_at" field. +func (u *PaymentOrderUpsert) SetRefundRequestedAt(v time.Time) *PaymentOrderUpsert { + u.Set(paymentorder.FieldRefundRequestedAt, v) + return u +} + +// UpdateRefundRequestedAt sets the "refund_requested_at" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateRefundRequestedAt() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldRefundRequestedAt) + return u +} + +// ClearRefundRequestedAt clears the value of the "refund_requested_at" field. +func (u *PaymentOrderUpsert) ClearRefundRequestedAt() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldRefundRequestedAt) + return u +} + +// SetRefundRequestReason sets the "refund_request_reason" field. +func (u *PaymentOrderUpsert) SetRefundRequestReason(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldRefundRequestReason, v) + return u +} + +// UpdateRefundRequestReason sets the "refund_request_reason" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateRefundRequestReason() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldRefundRequestReason) + return u +} + +// ClearRefundRequestReason clears the value of the "refund_request_reason" field. +func (u *PaymentOrderUpsert) ClearRefundRequestReason() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldRefundRequestReason) + return u +} + +// SetRefundRequestedBy sets the "refund_requested_by" field. +func (u *PaymentOrderUpsert) SetRefundRequestedBy(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldRefundRequestedBy, v) + return u +} + +// UpdateRefundRequestedBy sets the "refund_requested_by" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateRefundRequestedBy() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldRefundRequestedBy) + return u +} + +// ClearRefundRequestedBy clears the value of the "refund_requested_by" field. +func (u *PaymentOrderUpsert) ClearRefundRequestedBy() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldRefundRequestedBy) + return u +} + +// SetExpiresAt sets the "expires_at" field. +func (u *PaymentOrderUpsert) SetExpiresAt(v time.Time) *PaymentOrderUpsert { + u.Set(paymentorder.FieldExpiresAt, v) + return u +} + +// UpdateExpiresAt sets the "expires_at" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateExpiresAt() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldExpiresAt) + return u +} + +// SetPaidAt sets the "paid_at" field. +func (u *PaymentOrderUpsert) SetPaidAt(v time.Time) *PaymentOrderUpsert { + u.Set(paymentorder.FieldPaidAt, v) + return u +} + +// UpdatePaidAt sets the "paid_at" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdatePaidAt() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldPaidAt) + return u +} + +// ClearPaidAt clears the value of the "paid_at" field. +func (u *PaymentOrderUpsert) ClearPaidAt() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldPaidAt) + return u +} + +// SetCompletedAt sets the "completed_at" field. +func (u *PaymentOrderUpsert) SetCompletedAt(v time.Time) *PaymentOrderUpsert { + u.Set(paymentorder.FieldCompletedAt, v) + return u +} + +// UpdateCompletedAt sets the "completed_at" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateCompletedAt() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldCompletedAt) + return u +} + +// ClearCompletedAt clears the value of the "completed_at" field. +func (u *PaymentOrderUpsert) ClearCompletedAt() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldCompletedAt) + return u +} + +// SetFailedAt sets the "failed_at" field. +func (u *PaymentOrderUpsert) SetFailedAt(v time.Time) *PaymentOrderUpsert { + u.Set(paymentorder.FieldFailedAt, v) + return u +} + +// UpdateFailedAt sets the "failed_at" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateFailedAt() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldFailedAt) + return u +} + +// ClearFailedAt clears the value of the "failed_at" field. +func (u *PaymentOrderUpsert) ClearFailedAt() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldFailedAt) + return u +} + +// SetFailedReason sets the "failed_reason" field. +func (u *PaymentOrderUpsert) SetFailedReason(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldFailedReason, v) + return u +} + +// UpdateFailedReason sets the "failed_reason" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateFailedReason() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldFailedReason) + return u +} + +// ClearFailedReason clears the value of the "failed_reason" field. +func (u *PaymentOrderUpsert) ClearFailedReason() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldFailedReason) + return u +} + +// SetClientIP sets the "client_ip" field. +func (u *PaymentOrderUpsert) SetClientIP(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldClientIP, v) + return u +} + +// UpdateClientIP sets the "client_ip" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateClientIP() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldClientIP) + return u +} + +// SetSrcHost sets the "src_host" field. +func (u *PaymentOrderUpsert) SetSrcHost(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldSrcHost, v) + return u +} + +// UpdateSrcHost sets the "src_host" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateSrcHost() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldSrcHost) + return u +} + +// SetSrcURL sets the "src_url" field. +func (u *PaymentOrderUpsert) SetSrcURL(v string) *PaymentOrderUpsert { + u.Set(paymentorder.FieldSrcURL, v) + return u +} + +// UpdateSrcURL sets the "src_url" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateSrcURL() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldSrcURL) + return u +} + +// ClearSrcURL clears the value of the "src_url" field. +func (u *PaymentOrderUpsert) ClearSrcURL() *PaymentOrderUpsert { + u.SetNull(paymentorder.FieldSrcURL) + return u +} + +// SetUpdatedAt sets the "updated_at" field. +func (u *PaymentOrderUpsert) SetUpdatedAt(v time.Time) *PaymentOrderUpsert { + u.Set(paymentorder.FieldUpdatedAt, v) + return u +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *PaymentOrderUpsert) UpdateUpdatedAt() *PaymentOrderUpsert { + u.SetExcluded(paymentorder.FieldUpdatedAt) + return u +} + +// UpdateNewValues updates the mutable fields using the new values that were set on create. +// Using this option is equivalent to using: +// +// client.PaymentOrder.Create(). +// OnConflict( +// sql.ResolveWithNewValues(), +// ). +// Exec(ctx) +func (u *PaymentOrderUpsertOne) UpdateNewValues() *PaymentOrderUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { + if _, exists := u.create.mutation.CreatedAt(); exists { + s.SetIgnore(paymentorder.FieldCreatedAt) + } + })) + return u +} + +// Ignore sets each column to itself in case of conflict. +// Using this option is equivalent to using: +// +// client.PaymentOrder.Create(). +// OnConflict(sql.ResolveWithIgnore()). +// Exec(ctx) +func (u *PaymentOrderUpsertOne) Ignore() *PaymentOrderUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) + return u +} + +// DoNothing configures the conflict_action to `DO NOTHING`. +// Supported only by SQLite and PostgreSQL. +func (u *PaymentOrderUpsertOne) DoNothing() *PaymentOrderUpsertOne { + u.create.conflict = append(u.create.conflict, sql.DoNothing()) + return u +} + +// Update allows overriding fields `UPDATE` values. See the PaymentOrderCreate.OnConflict +// documentation for more info. +func (u *PaymentOrderUpsertOne) Update(set func(*PaymentOrderUpsert)) *PaymentOrderUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { + set(&PaymentOrderUpsert{UpdateSet: update}) + })) + return u +} + +// SetUserID sets the "user_id" field. +func (u *PaymentOrderUpsertOne) SetUserID(v int64) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetUserID(v) + }) +} + +// UpdateUserID sets the "user_id" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateUserID() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateUserID() + }) +} + +// SetUserEmail sets the "user_email" field. +func (u *PaymentOrderUpsertOne) SetUserEmail(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetUserEmail(v) + }) +} + +// UpdateUserEmail sets the "user_email" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateUserEmail() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateUserEmail() + }) +} + +// SetUserName sets the "user_name" field. +func (u *PaymentOrderUpsertOne) SetUserName(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetUserName(v) + }) +} + +// UpdateUserName sets the "user_name" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateUserName() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateUserName() + }) +} + +// SetUserNotes sets the "user_notes" field. +func (u *PaymentOrderUpsertOne) SetUserNotes(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetUserNotes(v) + }) +} + +// UpdateUserNotes sets the "user_notes" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateUserNotes() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateUserNotes() + }) +} + +// ClearUserNotes clears the value of the "user_notes" field. +func (u *PaymentOrderUpsertOne) ClearUserNotes() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearUserNotes() + }) +} + +// SetAmount sets the "amount" field. +func (u *PaymentOrderUpsertOne) SetAmount(v float64) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetAmount(v) + }) +} + +// AddAmount adds v to the "amount" field. +func (u *PaymentOrderUpsertOne) AddAmount(v float64) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.AddAmount(v) + }) +} + +// UpdateAmount sets the "amount" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateAmount() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateAmount() + }) +} + +// SetPayAmount sets the "pay_amount" field. +func (u *PaymentOrderUpsertOne) SetPayAmount(v float64) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetPayAmount(v) + }) +} + +// AddPayAmount adds v to the "pay_amount" field. +func (u *PaymentOrderUpsertOne) AddPayAmount(v float64) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.AddPayAmount(v) + }) +} + +// UpdatePayAmount sets the "pay_amount" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdatePayAmount() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdatePayAmount() + }) +} + +// SetFeeRate sets the "fee_rate" field. +func (u *PaymentOrderUpsertOne) SetFeeRate(v float64) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetFeeRate(v) + }) +} + +// AddFeeRate adds v to the "fee_rate" field. +func (u *PaymentOrderUpsertOne) AddFeeRate(v float64) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.AddFeeRate(v) + }) +} + +// UpdateFeeRate sets the "fee_rate" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateFeeRate() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateFeeRate() + }) +} + +// SetRechargeCode sets the "recharge_code" field. +func (u *PaymentOrderUpsertOne) SetRechargeCode(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetRechargeCode(v) + }) +} + +// UpdateRechargeCode sets the "recharge_code" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateRechargeCode() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateRechargeCode() + }) +} + +// SetPaymentType sets the "payment_type" field. +func (u *PaymentOrderUpsertOne) SetPaymentType(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetPaymentType(v) + }) +} + +// UpdatePaymentType sets the "payment_type" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdatePaymentType() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdatePaymentType() + }) +} + +// SetPaymentTradeNo sets the "payment_trade_no" field. +func (u *PaymentOrderUpsertOne) SetPaymentTradeNo(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetPaymentTradeNo(v) + }) +} + +// UpdatePaymentTradeNo sets the "payment_trade_no" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdatePaymentTradeNo() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdatePaymentTradeNo() + }) +} + +// SetPayURL sets the "pay_url" field. +func (u *PaymentOrderUpsertOne) SetPayURL(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetPayURL(v) + }) +} + +// UpdatePayURL sets the "pay_url" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdatePayURL() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdatePayURL() + }) +} + +// ClearPayURL clears the value of the "pay_url" field. +func (u *PaymentOrderUpsertOne) ClearPayURL() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearPayURL() + }) +} + +// SetQrCode sets the "qr_code" field. +func (u *PaymentOrderUpsertOne) SetQrCode(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetQrCode(v) + }) +} + +// UpdateQrCode sets the "qr_code" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateQrCode() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateQrCode() + }) +} + +// ClearQrCode clears the value of the "qr_code" field. +func (u *PaymentOrderUpsertOne) ClearQrCode() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearQrCode() + }) +} + +// SetQrCodeImg sets the "qr_code_img" field. +func (u *PaymentOrderUpsertOne) SetQrCodeImg(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetQrCodeImg(v) + }) +} + +// UpdateQrCodeImg sets the "qr_code_img" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateQrCodeImg() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateQrCodeImg() + }) +} + +// ClearQrCodeImg clears the value of the "qr_code_img" field. +func (u *PaymentOrderUpsertOne) ClearQrCodeImg() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearQrCodeImg() + }) +} + +// SetOrderType sets the "order_type" field. +func (u *PaymentOrderUpsertOne) SetOrderType(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetOrderType(v) + }) +} + +// UpdateOrderType sets the "order_type" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateOrderType() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateOrderType() + }) +} + +// SetPlanID sets the "plan_id" field. +func (u *PaymentOrderUpsertOne) SetPlanID(v int64) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetPlanID(v) + }) +} + +// AddPlanID adds v to the "plan_id" field. +func (u *PaymentOrderUpsertOne) AddPlanID(v int64) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.AddPlanID(v) + }) +} + +// UpdatePlanID sets the "plan_id" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdatePlanID() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdatePlanID() + }) +} + +// ClearPlanID clears the value of the "plan_id" field. +func (u *PaymentOrderUpsertOne) ClearPlanID() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearPlanID() + }) +} + +// SetSubscriptionGroupID sets the "subscription_group_id" field. +func (u *PaymentOrderUpsertOne) SetSubscriptionGroupID(v int64) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetSubscriptionGroupID(v) + }) +} + +// AddSubscriptionGroupID adds v to the "subscription_group_id" field. +func (u *PaymentOrderUpsertOne) AddSubscriptionGroupID(v int64) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.AddSubscriptionGroupID(v) + }) +} + +// UpdateSubscriptionGroupID sets the "subscription_group_id" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateSubscriptionGroupID() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateSubscriptionGroupID() + }) +} + +// ClearSubscriptionGroupID clears the value of the "subscription_group_id" field. +func (u *PaymentOrderUpsertOne) ClearSubscriptionGroupID() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearSubscriptionGroupID() + }) +} + +// SetSubscriptionDays sets the "subscription_days" field. +func (u *PaymentOrderUpsertOne) SetSubscriptionDays(v int) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetSubscriptionDays(v) + }) +} + +// AddSubscriptionDays adds v to the "subscription_days" field. +func (u *PaymentOrderUpsertOne) AddSubscriptionDays(v int) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.AddSubscriptionDays(v) + }) +} + +// UpdateSubscriptionDays sets the "subscription_days" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateSubscriptionDays() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateSubscriptionDays() + }) +} + +// ClearSubscriptionDays clears the value of the "subscription_days" field. +func (u *PaymentOrderUpsertOne) ClearSubscriptionDays() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearSubscriptionDays() + }) +} + +// SetProviderInstanceID sets the "provider_instance_id" field. +func (u *PaymentOrderUpsertOne) SetProviderInstanceID(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetProviderInstanceID(v) + }) +} + +// UpdateProviderInstanceID sets the "provider_instance_id" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateProviderInstanceID() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateProviderInstanceID() + }) +} + +// ClearProviderInstanceID clears the value of the "provider_instance_id" field. +func (u *PaymentOrderUpsertOne) ClearProviderInstanceID() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearProviderInstanceID() + }) +} + +// SetStatus sets the "status" field. +func (u *PaymentOrderUpsertOne) SetStatus(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetStatus(v) + }) +} + +// UpdateStatus sets the "status" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateStatus() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateStatus() + }) +} + +// SetRefundAmount sets the "refund_amount" field. +func (u *PaymentOrderUpsertOne) SetRefundAmount(v float64) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetRefundAmount(v) + }) +} + +// AddRefundAmount adds v to the "refund_amount" field. +func (u *PaymentOrderUpsertOne) AddRefundAmount(v float64) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.AddRefundAmount(v) + }) +} + +// UpdateRefundAmount sets the "refund_amount" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateRefundAmount() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateRefundAmount() + }) +} + +// SetRefundReason sets the "refund_reason" field. +func (u *PaymentOrderUpsertOne) SetRefundReason(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetRefundReason(v) + }) +} + +// UpdateRefundReason sets the "refund_reason" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateRefundReason() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateRefundReason() + }) +} + +// ClearRefundReason clears the value of the "refund_reason" field. +func (u *PaymentOrderUpsertOne) ClearRefundReason() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearRefundReason() + }) +} + +// SetRefundAt sets the "refund_at" field. +func (u *PaymentOrderUpsertOne) SetRefundAt(v time.Time) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetRefundAt(v) + }) +} + +// UpdateRefundAt sets the "refund_at" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateRefundAt() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateRefundAt() + }) +} + +// ClearRefundAt clears the value of the "refund_at" field. +func (u *PaymentOrderUpsertOne) ClearRefundAt() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearRefundAt() + }) +} + +// SetForceRefund sets the "force_refund" field. +func (u *PaymentOrderUpsertOne) SetForceRefund(v bool) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetForceRefund(v) + }) +} + +// UpdateForceRefund sets the "force_refund" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateForceRefund() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateForceRefund() + }) +} + +// SetRefundRequestedAt sets the "refund_requested_at" field. +func (u *PaymentOrderUpsertOne) SetRefundRequestedAt(v time.Time) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetRefundRequestedAt(v) + }) +} + +// UpdateRefundRequestedAt sets the "refund_requested_at" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateRefundRequestedAt() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateRefundRequestedAt() + }) +} + +// ClearRefundRequestedAt clears the value of the "refund_requested_at" field. +func (u *PaymentOrderUpsertOne) ClearRefundRequestedAt() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearRefundRequestedAt() + }) +} + +// SetRefundRequestReason sets the "refund_request_reason" field. +func (u *PaymentOrderUpsertOne) SetRefundRequestReason(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetRefundRequestReason(v) + }) +} + +// UpdateRefundRequestReason sets the "refund_request_reason" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateRefundRequestReason() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateRefundRequestReason() + }) +} + +// ClearRefundRequestReason clears the value of the "refund_request_reason" field. +func (u *PaymentOrderUpsertOne) ClearRefundRequestReason() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearRefundRequestReason() + }) +} + +// SetRefundRequestedBy sets the "refund_requested_by" field. +func (u *PaymentOrderUpsertOne) SetRefundRequestedBy(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetRefundRequestedBy(v) + }) +} + +// UpdateRefundRequestedBy sets the "refund_requested_by" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateRefundRequestedBy() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateRefundRequestedBy() + }) +} + +// ClearRefundRequestedBy clears the value of the "refund_requested_by" field. +func (u *PaymentOrderUpsertOne) ClearRefundRequestedBy() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearRefundRequestedBy() + }) +} + +// SetExpiresAt sets the "expires_at" field. +func (u *PaymentOrderUpsertOne) SetExpiresAt(v time.Time) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetExpiresAt(v) + }) +} + +// UpdateExpiresAt sets the "expires_at" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateExpiresAt() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateExpiresAt() + }) +} + +// SetPaidAt sets the "paid_at" field. +func (u *PaymentOrderUpsertOne) SetPaidAt(v time.Time) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetPaidAt(v) + }) +} + +// UpdatePaidAt sets the "paid_at" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdatePaidAt() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdatePaidAt() + }) +} + +// ClearPaidAt clears the value of the "paid_at" field. +func (u *PaymentOrderUpsertOne) ClearPaidAt() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearPaidAt() + }) +} + +// SetCompletedAt sets the "completed_at" field. +func (u *PaymentOrderUpsertOne) SetCompletedAt(v time.Time) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetCompletedAt(v) + }) +} + +// UpdateCompletedAt sets the "completed_at" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateCompletedAt() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateCompletedAt() + }) +} + +// ClearCompletedAt clears the value of the "completed_at" field. +func (u *PaymentOrderUpsertOne) ClearCompletedAt() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearCompletedAt() + }) +} + +// SetFailedAt sets the "failed_at" field. +func (u *PaymentOrderUpsertOne) SetFailedAt(v time.Time) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetFailedAt(v) + }) +} + +// UpdateFailedAt sets the "failed_at" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateFailedAt() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateFailedAt() + }) +} + +// ClearFailedAt clears the value of the "failed_at" field. +func (u *PaymentOrderUpsertOne) ClearFailedAt() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearFailedAt() + }) +} + +// SetFailedReason sets the "failed_reason" field. +func (u *PaymentOrderUpsertOne) SetFailedReason(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetFailedReason(v) + }) +} + +// UpdateFailedReason sets the "failed_reason" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateFailedReason() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateFailedReason() + }) +} + +// ClearFailedReason clears the value of the "failed_reason" field. +func (u *PaymentOrderUpsertOne) ClearFailedReason() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearFailedReason() + }) +} + +// SetClientIP sets the "client_ip" field. +func (u *PaymentOrderUpsertOne) SetClientIP(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetClientIP(v) + }) +} + +// UpdateClientIP sets the "client_ip" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateClientIP() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateClientIP() + }) +} + +// SetSrcHost sets the "src_host" field. +func (u *PaymentOrderUpsertOne) SetSrcHost(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetSrcHost(v) + }) +} + +// UpdateSrcHost sets the "src_host" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateSrcHost() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateSrcHost() + }) +} + +// SetSrcURL sets the "src_url" field. +func (u *PaymentOrderUpsertOne) SetSrcURL(v string) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetSrcURL(v) + }) +} + +// UpdateSrcURL sets the "src_url" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateSrcURL() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateSrcURL() + }) +} + +// ClearSrcURL clears the value of the "src_url" field. +func (u *PaymentOrderUpsertOne) ClearSrcURL() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearSrcURL() + }) +} + +// SetUpdatedAt sets the "updated_at" field. +func (u *PaymentOrderUpsertOne) SetUpdatedAt(v time.Time) *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetUpdatedAt(v) + }) +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *PaymentOrderUpsertOne) UpdateUpdatedAt() *PaymentOrderUpsertOne { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateUpdatedAt() + }) +} + +// Exec executes the query. +func (u *PaymentOrderUpsertOne) Exec(ctx context.Context) error { + if len(u.create.conflict) == 0 { + return errors.New("ent: missing options for PaymentOrderCreate.OnConflict") + } + return u.create.Exec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (u *PaymentOrderUpsertOne) ExecX(ctx context.Context) { + if err := u.create.Exec(ctx); err != nil { + panic(err) + } +} + +// Exec executes the UPSERT query and returns the inserted/updated ID. +func (u *PaymentOrderUpsertOne) ID(ctx context.Context) (id int64, err error) { + node, err := u.create.Save(ctx) + if err != nil { + return id, err + } + return node.ID, nil +} + +// IDX is like ID, but panics if an error occurs. +func (u *PaymentOrderUpsertOne) IDX(ctx context.Context) int64 { + id, err := u.ID(ctx) + if err != nil { + panic(err) + } + return id +} + +// PaymentOrderCreateBulk is the builder for creating many PaymentOrder entities in bulk. +type PaymentOrderCreateBulk struct { + config + err error + builders []*PaymentOrderCreate + conflict []sql.ConflictOption +} + +// Save creates the PaymentOrder entities in the database. +func (_c *PaymentOrderCreateBulk) Save(ctx context.Context) ([]*PaymentOrder, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*PaymentOrder, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { + func(i int, root context.Context) { + builder := _c.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PaymentOrderMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.OnConflict = _c.conflict + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + if specs[i].ID.Value != nil { + id := specs[i].ID.Value.(int64) + nodes[i].ID = int64(id) + } + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (_c *PaymentOrderCreateBulk) SaveX(ctx context.Context) []*PaymentOrder { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *PaymentOrderCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *PaymentOrderCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause +// of the `INSERT` statement. For example: +// +// client.PaymentOrder.CreateBulk(builders...). +// OnConflict( +// // Update the row with the new values +// // the was proposed for insertion. +// sql.ResolveWithNewValues(), +// ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.PaymentOrderUpsert) { +// SetUserID(v+v). +// }). +// Exec(ctx) +func (_c *PaymentOrderCreateBulk) OnConflict(opts ...sql.ConflictOption) *PaymentOrderUpsertBulk { + _c.conflict = opts + return &PaymentOrderUpsertBulk{ + create: _c, + } +} + +// OnConflictColumns calls `OnConflict` and configures the columns +// as conflict target. Using this option is equivalent to using: +// +// client.PaymentOrder.Create(). +// OnConflict(sql.ConflictColumns(columns...)). +// Exec(ctx) +func (_c *PaymentOrderCreateBulk) OnConflictColumns(columns ...string) *PaymentOrderUpsertBulk { + _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) + return &PaymentOrderUpsertBulk{ + create: _c, + } +} + +// PaymentOrderUpsertBulk is the builder for "upsert"-ing +// a bulk of PaymentOrder nodes. +type PaymentOrderUpsertBulk struct { + create *PaymentOrderCreateBulk +} + +// UpdateNewValues updates the mutable fields using the new values that +// were set on create. Using this option is equivalent to using: +// +// client.PaymentOrder.Create(). +// OnConflict( +// sql.ResolveWithNewValues(), +// ). +// Exec(ctx) +func (u *PaymentOrderUpsertBulk) UpdateNewValues() *PaymentOrderUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { + for _, b := range u.create.builders { + if _, exists := b.mutation.CreatedAt(); exists { + s.SetIgnore(paymentorder.FieldCreatedAt) + } + } + })) + return u +} + +// Ignore sets each column to itself in case of conflict. +// Using this option is equivalent to using: +// +// client.PaymentOrder.Create(). +// OnConflict(sql.ResolveWithIgnore()). +// Exec(ctx) +func (u *PaymentOrderUpsertBulk) Ignore() *PaymentOrderUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) + return u +} + +// DoNothing configures the conflict_action to `DO NOTHING`. +// Supported only by SQLite and PostgreSQL. +func (u *PaymentOrderUpsertBulk) DoNothing() *PaymentOrderUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.DoNothing()) + return u +} + +// Update allows overriding fields `UPDATE` values. See the PaymentOrderCreateBulk.OnConflict +// documentation for more info. +func (u *PaymentOrderUpsertBulk) Update(set func(*PaymentOrderUpsert)) *PaymentOrderUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { + set(&PaymentOrderUpsert{UpdateSet: update}) + })) + return u +} + +// SetUserID sets the "user_id" field. +func (u *PaymentOrderUpsertBulk) SetUserID(v int64) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetUserID(v) + }) +} + +// UpdateUserID sets the "user_id" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateUserID() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateUserID() + }) +} + +// SetUserEmail sets the "user_email" field. +func (u *PaymentOrderUpsertBulk) SetUserEmail(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetUserEmail(v) + }) +} + +// UpdateUserEmail sets the "user_email" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateUserEmail() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateUserEmail() + }) +} + +// SetUserName sets the "user_name" field. +func (u *PaymentOrderUpsertBulk) SetUserName(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetUserName(v) + }) +} + +// UpdateUserName sets the "user_name" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateUserName() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateUserName() + }) +} + +// SetUserNotes sets the "user_notes" field. +func (u *PaymentOrderUpsertBulk) SetUserNotes(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetUserNotes(v) + }) +} + +// UpdateUserNotes sets the "user_notes" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateUserNotes() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateUserNotes() + }) +} + +// ClearUserNotes clears the value of the "user_notes" field. +func (u *PaymentOrderUpsertBulk) ClearUserNotes() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearUserNotes() + }) +} + +// SetAmount sets the "amount" field. +func (u *PaymentOrderUpsertBulk) SetAmount(v float64) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetAmount(v) + }) +} + +// AddAmount adds v to the "amount" field. +func (u *PaymentOrderUpsertBulk) AddAmount(v float64) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.AddAmount(v) + }) +} + +// UpdateAmount sets the "amount" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateAmount() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateAmount() + }) +} + +// SetPayAmount sets the "pay_amount" field. +func (u *PaymentOrderUpsertBulk) SetPayAmount(v float64) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetPayAmount(v) + }) +} + +// AddPayAmount adds v to the "pay_amount" field. +func (u *PaymentOrderUpsertBulk) AddPayAmount(v float64) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.AddPayAmount(v) + }) +} + +// UpdatePayAmount sets the "pay_amount" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdatePayAmount() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdatePayAmount() + }) +} + +// SetFeeRate sets the "fee_rate" field. +func (u *PaymentOrderUpsertBulk) SetFeeRate(v float64) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetFeeRate(v) + }) +} + +// AddFeeRate adds v to the "fee_rate" field. +func (u *PaymentOrderUpsertBulk) AddFeeRate(v float64) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.AddFeeRate(v) + }) +} + +// UpdateFeeRate sets the "fee_rate" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateFeeRate() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateFeeRate() + }) +} + +// SetRechargeCode sets the "recharge_code" field. +func (u *PaymentOrderUpsertBulk) SetRechargeCode(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetRechargeCode(v) + }) +} + +// UpdateRechargeCode sets the "recharge_code" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateRechargeCode() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateRechargeCode() + }) +} + +// SetPaymentType sets the "payment_type" field. +func (u *PaymentOrderUpsertBulk) SetPaymentType(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetPaymentType(v) + }) +} + +// UpdatePaymentType sets the "payment_type" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdatePaymentType() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdatePaymentType() + }) +} + +// SetPaymentTradeNo sets the "payment_trade_no" field. +func (u *PaymentOrderUpsertBulk) SetPaymentTradeNo(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetPaymentTradeNo(v) + }) +} + +// UpdatePaymentTradeNo sets the "payment_trade_no" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdatePaymentTradeNo() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdatePaymentTradeNo() + }) +} + +// SetPayURL sets the "pay_url" field. +func (u *PaymentOrderUpsertBulk) SetPayURL(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetPayURL(v) + }) +} + +// UpdatePayURL sets the "pay_url" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdatePayURL() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdatePayURL() + }) +} + +// ClearPayURL clears the value of the "pay_url" field. +func (u *PaymentOrderUpsertBulk) ClearPayURL() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearPayURL() + }) +} + +// SetQrCode sets the "qr_code" field. +func (u *PaymentOrderUpsertBulk) SetQrCode(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetQrCode(v) + }) +} + +// UpdateQrCode sets the "qr_code" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateQrCode() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateQrCode() + }) +} + +// ClearQrCode clears the value of the "qr_code" field. +func (u *PaymentOrderUpsertBulk) ClearQrCode() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearQrCode() + }) +} + +// SetQrCodeImg sets the "qr_code_img" field. +func (u *PaymentOrderUpsertBulk) SetQrCodeImg(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetQrCodeImg(v) + }) +} + +// UpdateQrCodeImg sets the "qr_code_img" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateQrCodeImg() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateQrCodeImg() + }) +} + +// ClearQrCodeImg clears the value of the "qr_code_img" field. +func (u *PaymentOrderUpsertBulk) ClearQrCodeImg() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearQrCodeImg() + }) +} + +// SetOrderType sets the "order_type" field. +func (u *PaymentOrderUpsertBulk) SetOrderType(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetOrderType(v) + }) +} + +// UpdateOrderType sets the "order_type" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateOrderType() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateOrderType() + }) +} + +// SetPlanID sets the "plan_id" field. +func (u *PaymentOrderUpsertBulk) SetPlanID(v int64) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetPlanID(v) + }) +} + +// AddPlanID adds v to the "plan_id" field. +func (u *PaymentOrderUpsertBulk) AddPlanID(v int64) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.AddPlanID(v) + }) +} + +// UpdatePlanID sets the "plan_id" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdatePlanID() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdatePlanID() + }) +} + +// ClearPlanID clears the value of the "plan_id" field. +func (u *PaymentOrderUpsertBulk) ClearPlanID() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearPlanID() + }) +} + +// SetSubscriptionGroupID sets the "subscription_group_id" field. +func (u *PaymentOrderUpsertBulk) SetSubscriptionGroupID(v int64) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetSubscriptionGroupID(v) + }) +} + +// AddSubscriptionGroupID adds v to the "subscription_group_id" field. +func (u *PaymentOrderUpsertBulk) AddSubscriptionGroupID(v int64) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.AddSubscriptionGroupID(v) + }) +} + +// UpdateSubscriptionGroupID sets the "subscription_group_id" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateSubscriptionGroupID() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateSubscriptionGroupID() + }) +} + +// ClearSubscriptionGroupID clears the value of the "subscription_group_id" field. +func (u *PaymentOrderUpsertBulk) ClearSubscriptionGroupID() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearSubscriptionGroupID() + }) +} + +// SetSubscriptionDays sets the "subscription_days" field. +func (u *PaymentOrderUpsertBulk) SetSubscriptionDays(v int) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetSubscriptionDays(v) + }) +} + +// AddSubscriptionDays adds v to the "subscription_days" field. +func (u *PaymentOrderUpsertBulk) AddSubscriptionDays(v int) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.AddSubscriptionDays(v) + }) +} + +// UpdateSubscriptionDays sets the "subscription_days" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateSubscriptionDays() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateSubscriptionDays() + }) +} + +// ClearSubscriptionDays clears the value of the "subscription_days" field. +func (u *PaymentOrderUpsertBulk) ClearSubscriptionDays() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearSubscriptionDays() + }) +} + +// SetProviderInstanceID sets the "provider_instance_id" field. +func (u *PaymentOrderUpsertBulk) SetProviderInstanceID(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetProviderInstanceID(v) + }) +} + +// UpdateProviderInstanceID sets the "provider_instance_id" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateProviderInstanceID() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateProviderInstanceID() + }) +} + +// ClearProviderInstanceID clears the value of the "provider_instance_id" field. +func (u *PaymentOrderUpsertBulk) ClearProviderInstanceID() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearProviderInstanceID() + }) +} + +// SetStatus sets the "status" field. +func (u *PaymentOrderUpsertBulk) SetStatus(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetStatus(v) + }) +} + +// UpdateStatus sets the "status" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateStatus() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateStatus() + }) +} + +// SetRefundAmount sets the "refund_amount" field. +func (u *PaymentOrderUpsertBulk) SetRefundAmount(v float64) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetRefundAmount(v) + }) +} + +// AddRefundAmount adds v to the "refund_amount" field. +func (u *PaymentOrderUpsertBulk) AddRefundAmount(v float64) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.AddRefundAmount(v) + }) +} + +// UpdateRefundAmount sets the "refund_amount" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateRefundAmount() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateRefundAmount() + }) +} + +// SetRefundReason sets the "refund_reason" field. +func (u *PaymentOrderUpsertBulk) SetRefundReason(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetRefundReason(v) + }) +} + +// UpdateRefundReason sets the "refund_reason" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateRefundReason() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateRefundReason() + }) +} + +// ClearRefundReason clears the value of the "refund_reason" field. +func (u *PaymentOrderUpsertBulk) ClearRefundReason() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearRefundReason() + }) +} + +// SetRefundAt sets the "refund_at" field. +func (u *PaymentOrderUpsertBulk) SetRefundAt(v time.Time) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetRefundAt(v) + }) +} + +// UpdateRefundAt sets the "refund_at" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateRefundAt() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateRefundAt() + }) +} + +// ClearRefundAt clears the value of the "refund_at" field. +func (u *PaymentOrderUpsertBulk) ClearRefundAt() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearRefundAt() + }) +} + +// SetForceRefund sets the "force_refund" field. +func (u *PaymentOrderUpsertBulk) SetForceRefund(v bool) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetForceRefund(v) + }) +} + +// UpdateForceRefund sets the "force_refund" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateForceRefund() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateForceRefund() + }) +} + +// SetRefundRequestedAt sets the "refund_requested_at" field. +func (u *PaymentOrderUpsertBulk) SetRefundRequestedAt(v time.Time) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetRefundRequestedAt(v) + }) +} + +// UpdateRefundRequestedAt sets the "refund_requested_at" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateRefundRequestedAt() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateRefundRequestedAt() + }) +} + +// ClearRefundRequestedAt clears the value of the "refund_requested_at" field. +func (u *PaymentOrderUpsertBulk) ClearRefundRequestedAt() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearRefundRequestedAt() + }) +} + +// SetRefundRequestReason sets the "refund_request_reason" field. +func (u *PaymentOrderUpsertBulk) SetRefundRequestReason(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetRefundRequestReason(v) + }) +} + +// UpdateRefundRequestReason sets the "refund_request_reason" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateRefundRequestReason() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateRefundRequestReason() + }) +} + +// ClearRefundRequestReason clears the value of the "refund_request_reason" field. +func (u *PaymentOrderUpsertBulk) ClearRefundRequestReason() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearRefundRequestReason() + }) +} + +// SetRefundRequestedBy sets the "refund_requested_by" field. +func (u *PaymentOrderUpsertBulk) SetRefundRequestedBy(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetRefundRequestedBy(v) + }) +} + +// UpdateRefundRequestedBy sets the "refund_requested_by" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateRefundRequestedBy() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateRefundRequestedBy() + }) +} + +// ClearRefundRequestedBy clears the value of the "refund_requested_by" field. +func (u *PaymentOrderUpsertBulk) ClearRefundRequestedBy() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearRefundRequestedBy() + }) +} + +// SetExpiresAt sets the "expires_at" field. +func (u *PaymentOrderUpsertBulk) SetExpiresAt(v time.Time) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetExpiresAt(v) + }) +} + +// UpdateExpiresAt sets the "expires_at" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateExpiresAt() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateExpiresAt() + }) +} + +// SetPaidAt sets the "paid_at" field. +func (u *PaymentOrderUpsertBulk) SetPaidAt(v time.Time) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetPaidAt(v) + }) +} + +// UpdatePaidAt sets the "paid_at" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdatePaidAt() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdatePaidAt() + }) +} + +// ClearPaidAt clears the value of the "paid_at" field. +func (u *PaymentOrderUpsertBulk) ClearPaidAt() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearPaidAt() + }) +} + +// SetCompletedAt sets the "completed_at" field. +func (u *PaymentOrderUpsertBulk) SetCompletedAt(v time.Time) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetCompletedAt(v) + }) +} + +// UpdateCompletedAt sets the "completed_at" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateCompletedAt() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateCompletedAt() + }) +} + +// ClearCompletedAt clears the value of the "completed_at" field. +func (u *PaymentOrderUpsertBulk) ClearCompletedAt() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearCompletedAt() + }) +} + +// SetFailedAt sets the "failed_at" field. +func (u *PaymentOrderUpsertBulk) SetFailedAt(v time.Time) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetFailedAt(v) + }) +} + +// UpdateFailedAt sets the "failed_at" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateFailedAt() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateFailedAt() + }) +} + +// ClearFailedAt clears the value of the "failed_at" field. +func (u *PaymentOrderUpsertBulk) ClearFailedAt() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearFailedAt() + }) +} + +// SetFailedReason sets the "failed_reason" field. +func (u *PaymentOrderUpsertBulk) SetFailedReason(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetFailedReason(v) + }) +} + +// UpdateFailedReason sets the "failed_reason" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateFailedReason() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateFailedReason() + }) +} + +// ClearFailedReason clears the value of the "failed_reason" field. +func (u *PaymentOrderUpsertBulk) ClearFailedReason() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearFailedReason() + }) +} + +// SetClientIP sets the "client_ip" field. +func (u *PaymentOrderUpsertBulk) SetClientIP(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetClientIP(v) + }) +} + +// UpdateClientIP sets the "client_ip" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateClientIP() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateClientIP() + }) +} + +// SetSrcHost sets the "src_host" field. +func (u *PaymentOrderUpsertBulk) SetSrcHost(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetSrcHost(v) + }) +} + +// UpdateSrcHost sets the "src_host" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateSrcHost() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateSrcHost() + }) +} + +// SetSrcURL sets the "src_url" field. +func (u *PaymentOrderUpsertBulk) SetSrcURL(v string) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetSrcURL(v) + }) +} + +// UpdateSrcURL sets the "src_url" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateSrcURL() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateSrcURL() + }) +} + +// ClearSrcURL clears the value of the "src_url" field. +func (u *PaymentOrderUpsertBulk) ClearSrcURL() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.ClearSrcURL() + }) +} + +// SetUpdatedAt sets the "updated_at" field. +func (u *PaymentOrderUpsertBulk) SetUpdatedAt(v time.Time) *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.SetUpdatedAt(v) + }) +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *PaymentOrderUpsertBulk) UpdateUpdatedAt() *PaymentOrderUpsertBulk { + return u.Update(func(s *PaymentOrderUpsert) { + s.UpdateUpdatedAt() + }) +} + +// Exec executes the query. +func (u *PaymentOrderUpsertBulk) Exec(ctx context.Context) error { + if u.create.err != nil { + return u.create.err + } + for i, b := range u.create.builders { + if len(b.conflict) != 0 { + return fmt.Errorf("ent: OnConflict was set for builder %d. Set it on the PaymentOrderCreateBulk instead", i) + } + } + if len(u.create.conflict) == 0 { + return errors.New("ent: missing options for PaymentOrderCreateBulk.OnConflict") + } + return u.create.Exec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (u *PaymentOrderUpsertBulk) ExecX(ctx context.Context) { + if err := u.create.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/backend/ent/paymentorder_delete.go b/backend/ent/paymentorder_delete.go new file mode 100644 index 0000000000..a4bc1bdf6d --- /dev/null +++ b/backend/ent/paymentorder_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/paymentorder" + "github.com/Wei-Shaw/sub2api/ent/predicate" +) + +// PaymentOrderDelete is the builder for deleting a PaymentOrder entity. +type PaymentOrderDelete struct { + config + hooks []Hook + mutation *PaymentOrderMutation +} + +// Where appends a list predicates to the PaymentOrderDelete builder. +func (_d *PaymentOrderDelete) Where(ps ...predicate.PaymentOrder) *PaymentOrderDelete { + _d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (_d *PaymentOrderDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *PaymentOrderDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (_d *PaymentOrderDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(paymentorder.Table, sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64)) + if ps := _d.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + _d.mutation.done = true + return affected, err +} + +// PaymentOrderDeleteOne is the builder for deleting a single PaymentOrder entity. +type PaymentOrderDeleteOne struct { + _d *PaymentOrderDelete +} + +// Where appends a list predicates to the PaymentOrderDelete builder. +func (_d *PaymentOrderDeleteOne) Where(ps ...predicate.PaymentOrder) *PaymentOrderDeleteOne { + _d._d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query. +func (_d *PaymentOrderDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{paymentorder.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *PaymentOrderDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/backend/ent/paymentorder_query.go b/backend/ent/paymentorder_query.go new file mode 100644 index 0000000000..92fd74a73c --- /dev/null +++ b/backend/ent/paymentorder_query.go @@ -0,0 +1,643 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "math" + + "entgo.io/ent" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/paymentorder" + "github.com/Wei-Shaw/sub2api/ent/predicate" + "github.com/Wei-Shaw/sub2api/ent/user" +) + +// PaymentOrderQuery is the builder for querying PaymentOrder entities. +type PaymentOrderQuery struct { + config + ctx *QueryContext + order []paymentorder.OrderOption + inters []Interceptor + predicates []predicate.PaymentOrder + withUser *UserQuery + modifiers []func(*sql.Selector) + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the PaymentOrderQuery builder. +func (_q *PaymentOrderQuery) Where(ps ...predicate.PaymentOrder) *PaymentOrderQuery { + _q.predicates = append(_q.predicates, ps...) + return _q +} + +// Limit the number of records to be returned by this query. +func (_q *PaymentOrderQuery) Limit(limit int) *PaymentOrderQuery { + _q.ctx.Limit = &limit + return _q +} + +// Offset to start from. +func (_q *PaymentOrderQuery) Offset(offset int) *PaymentOrderQuery { + _q.ctx.Offset = &offset + return _q +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (_q *PaymentOrderQuery) Unique(unique bool) *PaymentOrderQuery { + _q.ctx.Unique = &unique + return _q +} + +// Order specifies how the records should be ordered. +func (_q *PaymentOrderQuery) Order(o ...paymentorder.OrderOption) *PaymentOrderQuery { + _q.order = append(_q.order, o...) + return _q +} + +// QueryUser chains the current query on the "user" edge. +func (_q *PaymentOrderQuery) QueryUser() *UserQuery { + query := (&UserClient{config: _q.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + selector := _q.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(paymentorder.Table, paymentorder.FieldID, selector), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, paymentorder.UserTable, paymentorder.UserColumn), + ) + fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first PaymentOrder entity from the query. +// Returns a *NotFoundError when no PaymentOrder was found. +func (_q *PaymentOrderQuery) First(ctx context.Context) (*PaymentOrder, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{paymentorder.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (_q *PaymentOrderQuery) FirstX(ctx context.Context) *PaymentOrder { + node, err := _q.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first PaymentOrder ID from the query. +// Returns a *NotFoundError when no PaymentOrder ID was found. +func (_q *PaymentOrderQuery) FirstID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{paymentorder.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (_q *PaymentOrderQuery) FirstIDX(ctx context.Context) int64 { + id, err := _q.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single PaymentOrder entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one PaymentOrder entity is found. +// Returns a *NotFoundError when no PaymentOrder entities are found. +func (_q *PaymentOrderQuery) Only(ctx context.Context) (*PaymentOrder, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{paymentorder.Label} + default: + return nil, &NotSingularError{paymentorder.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (_q *PaymentOrderQuery) OnlyX(ctx context.Context) *PaymentOrder { + node, err := _q.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only PaymentOrder ID in the query. +// Returns a *NotSingularError when more than one PaymentOrder ID is found. +// Returns a *NotFoundError when no entities are found. +func (_q *PaymentOrderQuery) OnlyID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{paymentorder.Label} + default: + err = &NotSingularError{paymentorder.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (_q *PaymentOrderQuery) OnlyIDX(ctx context.Context) int64 { + id, err := _q.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of PaymentOrders. +func (_q *PaymentOrderQuery) All(ctx context.Context) ([]*PaymentOrder, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*PaymentOrder, *PaymentOrderQuery]() + return withInterceptors[[]*PaymentOrder](ctx, _q, qr, _q.inters) +} + +// AllX is like All, but panics if an error occurs. +func (_q *PaymentOrderQuery) AllX(ctx context.Context) []*PaymentOrder { + nodes, err := _q.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of PaymentOrder IDs. +func (_q *PaymentOrderQuery) IDs(ctx context.Context) (ids []int64, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(paymentorder.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (_q *PaymentOrderQuery) IDsX(ctx context.Context) []int64 { + ids, err := _q.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (_q *PaymentOrderQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, _q, querierCount[*PaymentOrderQuery](), _q.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (_q *PaymentOrderQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (_q *PaymentOrderQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (_q *PaymentOrderQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the PaymentOrderQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (_q *PaymentOrderQuery) Clone() *PaymentOrderQuery { + if _q == nil { + return nil + } + return &PaymentOrderQuery{ + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]paymentorder.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.PaymentOrder{}, _q.predicates...), + withUser: _q.withUser.Clone(), + // clone intermediate query. + sql: _q.sql.Clone(), + path: _q.path, + } +} + +// WithUser tells the query-builder to eager-load the nodes that are connected to +// the "user" edge. The optional arguments are used to configure the query builder of the edge. +func (_q *PaymentOrderQuery) WithUser(opts ...func(*UserQuery)) *PaymentOrderQuery { + query := (&UserClient{config: _q.config}).Query() + for _, opt := range opts { + opt(query) + } + _q.withUser = query + return _q +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// UserID int64 `json:"user_id,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.PaymentOrder.Query(). +// GroupBy(paymentorder.FieldUserID). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (_q *PaymentOrderQuery) GroupBy(field string, fields ...string) *PaymentOrderGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &PaymentOrderGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields + grbuild.label = paymentorder.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// UserID int64 `json:"user_id,omitempty"` +// } +// +// client.PaymentOrder.Query(). +// Select(paymentorder.FieldUserID). +// Scan(ctx, &v) +func (_q *PaymentOrderQuery) Select(fields ...string) *PaymentOrderSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &PaymentOrderSelect{PaymentOrderQuery: _q} + sbuild.label = paymentorder.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a PaymentOrderSelect configured with the given aggregations. +func (_q *PaymentOrderQuery) Aggregate(fns ...AggregateFunc) *PaymentOrderSelect { + return _q.Select().Aggregate(fns...) +} + +func (_q *PaymentOrderQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { + if !paymentorder.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if _q.path != nil { + prev, err := _q.path(ctx) + if err != nil { + return err + } + _q.sql = prev + } + return nil +} + +func (_q *PaymentOrderQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*PaymentOrder, error) { + var ( + nodes = []*PaymentOrder{} + _spec = _q.querySpec() + loadedTypes = [1]bool{ + _q.withUser != nil, + } + ) + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*PaymentOrder).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &PaymentOrder{config: _q.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + if len(_q.modifiers) > 0 { + _spec.Modifiers = _q.modifiers + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := _q.withUser; query != nil { + if err := _q.loadUser(ctx, query, nodes, nil, + func(n *PaymentOrder, e *User) { n.Edges.User = e }); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (_q *PaymentOrderQuery) loadUser(ctx context.Context, query *UserQuery, nodes []*PaymentOrder, init func(*PaymentOrder), assign func(*PaymentOrder, *User)) error { + ids := make([]int64, 0, len(nodes)) + nodeids := make(map[int64][]*PaymentOrder) + for i := range nodes { + fk := nodes[i].UserID + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(user.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "user_id" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} + +func (_q *PaymentOrderQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + if len(_q.modifiers) > 0 { + _spec.Modifiers = _q.modifiers + } + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique + } + return sqlgraph.CountNodes(ctx, _q.driver, _spec) +} + +func (_q *PaymentOrderQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(paymentorder.Table, paymentorder.Columns, sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true + } + if fields := _q.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, paymentorder.FieldID) + for i := range fields { + if fields[i] != paymentorder.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + if _q.withUser != nil { + _spec.Node.AddColumnOnce(paymentorder.FieldUserID) + } + } + if ps := _q.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := _q.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := _q.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := _q.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (_q *PaymentOrderQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) + t1 := builder.Table(paymentorder.Table) + columns := _q.ctx.Fields + if len(columns) == 0 { + columns = paymentorder.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if _q.sql != nil { + selector = _q.sql + selector.Select(selector.Columns(columns...)...) + } + if _q.ctx.Unique != nil && *_q.ctx.Unique { + selector.Distinct() + } + for _, m := range _q.modifiers { + m(selector) + } + for _, p := range _q.predicates { + p(selector) + } + for _, p := range _q.order { + p(selector) + } + if offset := _q.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := _q.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// ForUpdate locks the selected rows against concurrent updates, and prevent them from being +// updated, deleted or "selected ... for update" by other sessions, until the transaction is +// either committed or rolled-back. +func (_q *PaymentOrderQuery) ForUpdate(opts ...sql.LockOption) *PaymentOrderQuery { + if _q.driver.Dialect() == dialect.Postgres { + _q.Unique(false) + } + _q.modifiers = append(_q.modifiers, func(s *sql.Selector) { + s.ForUpdate(opts...) + }) + return _q +} + +// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock +// on any rows that are read. Other sessions can read the rows, but cannot modify them +// until your transaction commits. +func (_q *PaymentOrderQuery) ForShare(opts ...sql.LockOption) *PaymentOrderQuery { + if _q.driver.Dialect() == dialect.Postgres { + _q.Unique(false) + } + _q.modifiers = append(_q.modifiers, func(s *sql.Selector) { + s.ForShare(opts...) + }) + return _q +} + +// PaymentOrderGroupBy is the group-by builder for PaymentOrder entities. +type PaymentOrderGroupBy struct { + selector + build *PaymentOrderQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (_g *PaymentOrderGroupBy) Aggregate(fns ...AggregateFunc) *PaymentOrderGroupBy { + _g.fns = append(_g.fns, fns...) + return _g +} + +// Scan applies the selector query and scans the result into the given value. +func (_g *PaymentOrderGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*PaymentOrderQuery, *PaymentOrderGroupBy](ctx, _g.build, _g, _g.build.inters, v) +} + +func (_g *PaymentOrderGroupBy) sqlScan(ctx context.Context, root *PaymentOrderQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*_g.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// PaymentOrderSelect is the builder for selecting fields of PaymentOrder entities. +type PaymentOrderSelect struct { + *PaymentOrderQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *PaymentOrderSelect) Aggregate(fns ...AggregateFunc) *PaymentOrderSelect { + _s.fns = append(_s.fns, fns...) + return _s +} + +// Scan applies the selector query and scans the result into the given value. +func (_s *PaymentOrderSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*PaymentOrderQuery, *PaymentOrderSelect](ctx, _s.PaymentOrderQuery, _s, _s.inters, v) +} + +func (_s *PaymentOrderSelect) sqlScan(ctx context.Context, root *PaymentOrderQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/backend/ent/paymentorder_update.go b/backend/ent/paymentorder_update.go new file mode 100644 index 0000000000..55c41c3b3d --- /dev/null +++ b/backend/ent/paymentorder_update.go @@ -0,0 +1,2039 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/paymentorder" + "github.com/Wei-Shaw/sub2api/ent/predicate" + "github.com/Wei-Shaw/sub2api/ent/user" +) + +// PaymentOrderUpdate is the builder for updating PaymentOrder entities. +type PaymentOrderUpdate struct { + config + hooks []Hook + mutation *PaymentOrderMutation +} + +// Where appends a list predicates to the PaymentOrderUpdate builder. +func (_u *PaymentOrderUpdate) Where(ps ...predicate.PaymentOrder) *PaymentOrderUpdate { + _u.mutation.Where(ps...) + return _u +} + +// SetUserID sets the "user_id" field. +func (_u *PaymentOrderUpdate) SetUserID(v int64) *PaymentOrderUpdate { + _u.mutation.SetUserID(v) + return _u +} + +// SetNillableUserID sets the "user_id" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableUserID(v *int64) *PaymentOrderUpdate { + if v != nil { + _u.SetUserID(*v) + } + return _u +} + +// SetUserEmail sets the "user_email" field. +func (_u *PaymentOrderUpdate) SetUserEmail(v string) *PaymentOrderUpdate { + _u.mutation.SetUserEmail(v) + return _u +} + +// SetNillableUserEmail sets the "user_email" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableUserEmail(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetUserEmail(*v) + } + return _u +} + +// SetUserName sets the "user_name" field. +func (_u *PaymentOrderUpdate) SetUserName(v string) *PaymentOrderUpdate { + _u.mutation.SetUserName(v) + return _u +} + +// SetNillableUserName sets the "user_name" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableUserName(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetUserName(*v) + } + return _u +} + +// SetUserNotes sets the "user_notes" field. +func (_u *PaymentOrderUpdate) SetUserNotes(v string) *PaymentOrderUpdate { + _u.mutation.SetUserNotes(v) + return _u +} + +// SetNillableUserNotes sets the "user_notes" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableUserNotes(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetUserNotes(*v) + } + return _u +} + +// ClearUserNotes clears the value of the "user_notes" field. +func (_u *PaymentOrderUpdate) ClearUserNotes() *PaymentOrderUpdate { + _u.mutation.ClearUserNotes() + return _u +} + +// SetAmount sets the "amount" field. +func (_u *PaymentOrderUpdate) SetAmount(v float64) *PaymentOrderUpdate { + _u.mutation.ResetAmount() + _u.mutation.SetAmount(v) + return _u +} + +// SetNillableAmount sets the "amount" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableAmount(v *float64) *PaymentOrderUpdate { + if v != nil { + _u.SetAmount(*v) + } + return _u +} + +// AddAmount adds value to the "amount" field. +func (_u *PaymentOrderUpdate) AddAmount(v float64) *PaymentOrderUpdate { + _u.mutation.AddAmount(v) + return _u +} + +// SetPayAmount sets the "pay_amount" field. +func (_u *PaymentOrderUpdate) SetPayAmount(v float64) *PaymentOrderUpdate { + _u.mutation.ResetPayAmount() + _u.mutation.SetPayAmount(v) + return _u +} + +// SetNillablePayAmount sets the "pay_amount" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillablePayAmount(v *float64) *PaymentOrderUpdate { + if v != nil { + _u.SetPayAmount(*v) + } + return _u +} + +// AddPayAmount adds value to the "pay_amount" field. +func (_u *PaymentOrderUpdate) AddPayAmount(v float64) *PaymentOrderUpdate { + _u.mutation.AddPayAmount(v) + return _u +} + +// SetFeeRate sets the "fee_rate" field. +func (_u *PaymentOrderUpdate) SetFeeRate(v float64) *PaymentOrderUpdate { + _u.mutation.ResetFeeRate() + _u.mutation.SetFeeRate(v) + return _u +} + +// SetNillableFeeRate sets the "fee_rate" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableFeeRate(v *float64) *PaymentOrderUpdate { + if v != nil { + _u.SetFeeRate(*v) + } + return _u +} + +// AddFeeRate adds value to the "fee_rate" field. +func (_u *PaymentOrderUpdate) AddFeeRate(v float64) *PaymentOrderUpdate { + _u.mutation.AddFeeRate(v) + return _u +} + +// SetRechargeCode sets the "recharge_code" field. +func (_u *PaymentOrderUpdate) SetRechargeCode(v string) *PaymentOrderUpdate { + _u.mutation.SetRechargeCode(v) + return _u +} + +// SetNillableRechargeCode sets the "recharge_code" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableRechargeCode(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetRechargeCode(*v) + } + return _u +} + +// SetPaymentType sets the "payment_type" field. +func (_u *PaymentOrderUpdate) SetPaymentType(v string) *PaymentOrderUpdate { + _u.mutation.SetPaymentType(v) + return _u +} + +// SetNillablePaymentType sets the "payment_type" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillablePaymentType(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetPaymentType(*v) + } + return _u +} + +// SetPaymentTradeNo sets the "payment_trade_no" field. +func (_u *PaymentOrderUpdate) SetPaymentTradeNo(v string) *PaymentOrderUpdate { + _u.mutation.SetPaymentTradeNo(v) + return _u +} + +// SetNillablePaymentTradeNo sets the "payment_trade_no" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillablePaymentTradeNo(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetPaymentTradeNo(*v) + } + return _u +} + +// SetPayURL sets the "pay_url" field. +func (_u *PaymentOrderUpdate) SetPayURL(v string) *PaymentOrderUpdate { + _u.mutation.SetPayURL(v) + return _u +} + +// SetNillablePayURL sets the "pay_url" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillablePayURL(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetPayURL(*v) + } + return _u +} + +// ClearPayURL clears the value of the "pay_url" field. +func (_u *PaymentOrderUpdate) ClearPayURL() *PaymentOrderUpdate { + _u.mutation.ClearPayURL() + return _u +} + +// SetQrCode sets the "qr_code" field. +func (_u *PaymentOrderUpdate) SetQrCode(v string) *PaymentOrderUpdate { + _u.mutation.SetQrCode(v) + return _u +} + +// SetNillableQrCode sets the "qr_code" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableQrCode(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetQrCode(*v) + } + return _u +} + +// ClearQrCode clears the value of the "qr_code" field. +func (_u *PaymentOrderUpdate) ClearQrCode() *PaymentOrderUpdate { + _u.mutation.ClearQrCode() + return _u +} + +// SetQrCodeImg sets the "qr_code_img" field. +func (_u *PaymentOrderUpdate) SetQrCodeImg(v string) *PaymentOrderUpdate { + _u.mutation.SetQrCodeImg(v) + return _u +} + +// SetNillableQrCodeImg sets the "qr_code_img" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableQrCodeImg(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetQrCodeImg(*v) + } + return _u +} + +// ClearQrCodeImg clears the value of the "qr_code_img" field. +func (_u *PaymentOrderUpdate) ClearQrCodeImg() *PaymentOrderUpdate { + _u.mutation.ClearQrCodeImg() + return _u +} + +// SetOrderType sets the "order_type" field. +func (_u *PaymentOrderUpdate) SetOrderType(v string) *PaymentOrderUpdate { + _u.mutation.SetOrderType(v) + return _u +} + +// SetNillableOrderType sets the "order_type" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableOrderType(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetOrderType(*v) + } + return _u +} + +// SetPlanID sets the "plan_id" field. +func (_u *PaymentOrderUpdate) SetPlanID(v int64) *PaymentOrderUpdate { + _u.mutation.ResetPlanID() + _u.mutation.SetPlanID(v) + return _u +} + +// SetNillablePlanID sets the "plan_id" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillablePlanID(v *int64) *PaymentOrderUpdate { + if v != nil { + _u.SetPlanID(*v) + } + return _u +} + +// AddPlanID adds value to the "plan_id" field. +func (_u *PaymentOrderUpdate) AddPlanID(v int64) *PaymentOrderUpdate { + _u.mutation.AddPlanID(v) + return _u +} + +// ClearPlanID clears the value of the "plan_id" field. +func (_u *PaymentOrderUpdate) ClearPlanID() *PaymentOrderUpdate { + _u.mutation.ClearPlanID() + return _u +} + +// SetSubscriptionGroupID sets the "subscription_group_id" field. +func (_u *PaymentOrderUpdate) SetSubscriptionGroupID(v int64) *PaymentOrderUpdate { + _u.mutation.ResetSubscriptionGroupID() + _u.mutation.SetSubscriptionGroupID(v) + return _u +} + +// SetNillableSubscriptionGroupID sets the "subscription_group_id" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableSubscriptionGroupID(v *int64) *PaymentOrderUpdate { + if v != nil { + _u.SetSubscriptionGroupID(*v) + } + return _u +} + +// AddSubscriptionGroupID adds value to the "subscription_group_id" field. +func (_u *PaymentOrderUpdate) AddSubscriptionGroupID(v int64) *PaymentOrderUpdate { + _u.mutation.AddSubscriptionGroupID(v) + return _u +} + +// ClearSubscriptionGroupID clears the value of the "subscription_group_id" field. +func (_u *PaymentOrderUpdate) ClearSubscriptionGroupID() *PaymentOrderUpdate { + _u.mutation.ClearSubscriptionGroupID() + return _u +} + +// SetSubscriptionDays sets the "subscription_days" field. +func (_u *PaymentOrderUpdate) SetSubscriptionDays(v int) *PaymentOrderUpdate { + _u.mutation.ResetSubscriptionDays() + _u.mutation.SetSubscriptionDays(v) + return _u +} + +// SetNillableSubscriptionDays sets the "subscription_days" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableSubscriptionDays(v *int) *PaymentOrderUpdate { + if v != nil { + _u.SetSubscriptionDays(*v) + } + return _u +} + +// AddSubscriptionDays adds value to the "subscription_days" field. +func (_u *PaymentOrderUpdate) AddSubscriptionDays(v int) *PaymentOrderUpdate { + _u.mutation.AddSubscriptionDays(v) + return _u +} + +// ClearSubscriptionDays clears the value of the "subscription_days" field. +func (_u *PaymentOrderUpdate) ClearSubscriptionDays() *PaymentOrderUpdate { + _u.mutation.ClearSubscriptionDays() + return _u +} + +// SetProviderInstanceID sets the "provider_instance_id" field. +func (_u *PaymentOrderUpdate) SetProviderInstanceID(v string) *PaymentOrderUpdate { + _u.mutation.SetProviderInstanceID(v) + return _u +} + +// SetNillableProviderInstanceID sets the "provider_instance_id" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableProviderInstanceID(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetProviderInstanceID(*v) + } + return _u +} + +// ClearProviderInstanceID clears the value of the "provider_instance_id" field. +func (_u *PaymentOrderUpdate) ClearProviderInstanceID() *PaymentOrderUpdate { + _u.mutation.ClearProviderInstanceID() + return _u +} + +// SetStatus sets the "status" field. +func (_u *PaymentOrderUpdate) SetStatus(v string) *PaymentOrderUpdate { + _u.mutation.SetStatus(v) + return _u +} + +// SetNillableStatus sets the "status" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableStatus(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetStatus(*v) + } + return _u +} + +// SetRefundAmount sets the "refund_amount" field. +func (_u *PaymentOrderUpdate) SetRefundAmount(v float64) *PaymentOrderUpdate { + _u.mutation.ResetRefundAmount() + _u.mutation.SetRefundAmount(v) + return _u +} + +// SetNillableRefundAmount sets the "refund_amount" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableRefundAmount(v *float64) *PaymentOrderUpdate { + if v != nil { + _u.SetRefundAmount(*v) + } + return _u +} + +// AddRefundAmount adds value to the "refund_amount" field. +func (_u *PaymentOrderUpdate) AddRefundAmount(v float64) *PaymentOrderUpdate { + _u.mutation.AddRefundAmount(v) + return _u +} + +// SetRefundReason sets the "refund_reason" field. +func (_u *PaymentOrderUpdate) SetRefundReason(v string) *PaymentOrderUpdate { + _u.mutation.SetRefundReason(v) + return _u +} + +// SetNillableRefundReason sets the "refund_reason" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableRefundReason(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetRefundReason(*v) + } + return _u +} + +// ClearRefundReason clears the value of the "refund_reason" field. +func (_u *PaymentOrderUpdate) ClearRefundReason() *PaymentOrderUpdate { + _u.mutation.ClearRefundReason() + return _u +} + +// SetRefundAt sets the "refund_at" field. +func (_u *PaymentOrderUpdate) SetRefundAt(v time.Time) *PaymentOrderUpdate { + _u.mutation.SetRefundAt(v) + return _u +} + +// SetNillableRefundAt sets the "refund_at" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableRefundAt(v *time.Time) *PaymentOrderUpdate { + if v != nil { + _u.SetRefundAt(*v) + } + return _u +} + +// ClearRefundAt clears the value of the "refund_at" field. +func (_u *PaymentOrderUpdate) ClearRefundAt() *PaymentOrderUpdate { + _u.mutation.ClearRefundAt() + return _u +} + +// SetForceRefund sets the "force_refund" field. +func (_u *PaymentOrderUpdate) SetForceRefund(v bool) *PaymentOrderUpdate { + _u.mutation.SetForceRefund(v) + return _u +} + +// SetNillableForceRefund sets the "force_refund" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableForceRefund(v *bool) *PaymentOrderUpdate { + if v != nil { + _u.SetForceRefund(*v) + } + return _u +} + +// SetRefundRequestedAt sets the "refund_requested_at" field. +func (_u *PaymentOrderUpdate) SetRefundRequestedAt(v time.Time) *PaymentOrderUpdate { + _u.mutation.SetRefundRequestedAt(v) + return _u +} + +// SetNillableRefundRequestedAt sets the "refund_requested_at" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableRefundRequestedAt(v *time.Time) *PaymentOrderUpdate { + if v != nil { + _u.SetRefundRequestedAt(*v) + } + return _u +} + +// ClearRefundRequestedAt clears the value of the "refund_requested_at" field. +func (_u *PaymentOrderUpdate) ClearRefundRequestedAt() *PaymentOrderUpdate { + _u.mutation.ClearRefundRequestedAt() + return _u +} + +// SetRefundRequestReason sets the "refund_request_reason" field. +func (_u *PaymentOrderUpdate) SetRefundRequestReason(v string) *PaymentOrderUpdate { + _u.mutation.SetRefundRequestReason(v) + return _u +} + +// SetNillableRefundRequestReason sets the "refund_request_reason" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableRefundRequestReason(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetRefundRequestReason(*v) + } + return _u +} + +// ClearRefundRequestReason clears the value of the "refund_request_reason" field. +func (_u *PaymentOrderUpdate) ClearRefundRequestReason() *PaymentOrderUpdate { + _u.mutation.ClearRefundRequestReason() + return _u +} + +// SetRefundRequestedBy sets the "refund_requested_by" field. +func (_u *PaymentOrderUpdate) SetRefundRequestedBy(v string) *PaymentOrderUpdate { + _u.mutation.SetRefundRequestedBy(v) + return _u +} + +// SetNillableRefundRequestedBy sets the "refund_requested_by" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableRefundRequestedBy(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetRefundRequestedBy(*v) + } + return _u +} + +// ClearRefundRequestedBy clears the value of the "refund_requested_by" field. +func (_u *PaymentOrderUpdate) ClearRefundRequestedBy() *PaymentOrderUpdate { + _u.mutation.ClearRefundRequestedBy() + return _u +} + +// SetExpiresAt sets the "expires_at" field. +func (_u *PaymentOrderUpdate) SetExpiresAt(v time.Time) *PaymentOrderUpdate { + _u.mutation.SetExpiresAt(v) + return _u +} + +// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableExpiresAt(v *time.Time) *PaymentOrderUpdate { + if v != nil { + _u.SetExpiresAt(*v) + } + return _u +} + +// SetPaidAt sets the "paid_at" field. +func (_u *PaymentOrderUpdate) SetPaidAt(v time.Time) *PaymentOrderUpdate { + _u.mutation.SetPaidAt(v) + return _u +} + +// SetNillablePaidAt sets the "paid_at" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillablePaidAt(v *time.Time) *PaymentOrderUpdate { + if v != nil { + _u.SetPaidAt(*v) + } + return _u +} + +// ClearPaidAt clears the value of the "paid_at" field. +func (_u *PaymentOrderUpdate) ClearPaidAt() *PaymentOrderUpdate { + _u.mutation.ClearPaidAt() + return _u +} + +// SetCompletedAt sets the "completed_at" field. +func (_u *PaymentOrderUpdate) SetCompletedAt(v time.Time) *PaymentOrderUpdate { + _u.mutation.SetCompletedAt(v) + return _u +} + +// SetNillableCompletedAt sets the "completed_at" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableCompletedAt(v *time.Time) *PaymentOrderUpdate { + if v != nil { + _u.SetCompletedAt(*v) + } + return _u +} + +// ClearCompletedAt clears the value of the "completed_at" field. +func (_u *PaymentOrderUpdate) ClearCompletedAt() *PaymentOrderUpdate { + _u.mutation.ClearCompletedAt() + return _u +} + +// SetFailedAt sets the "failed_at" field. +func (_u *PaymentOrderUpdate) SetFailedAt(v time.Time) *PaymentOrderUpdate { + _u.mutation.SetFailedAt(v) + return _u +} + +// SetNillableFailedAt sets the "failed_at" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableFailedAt(v *time.Time) *PaymentOrderUpdate { + if v != nil { + _u.SetFailedAt(*v) + } + return _u +} + +// ClearFailedAt clears the value of the "failed_at" field. +func (_u *PaymentOrderUpdate) ClearFailedAt() *PaymentOrderUpdate { + _u.mutation.ClearFailedAt() + return _u +} + +// SetFailedReason sets the "failed_reason" field. +func (_u *PaymentOrderUpdate) SetFailedReason(v string) *PaymentOrderUpdate { + _u.mutation.SetFailedReason(v) + return _u +} + +// SetNillableFailedReason sets the "failed_reason" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableFailedReason(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetFailedReason(*v) + } + return _u +} + +// ClearFailedReason clears the value of the "failed_reason" field. +func (_u *PaymentOrderUpdate) ClearFailedReason() *PaymentOrderUpdate { + _u.mutation.ClearFailedReason() + return _u +} + +// SetClientIP sets the "client_ip" field. +func (_u *PaymentOrderUpdate) SetClientIP(v string) *PaymentOrderUpdate { + _u.mutation.SetClientIP(v) + return _u +} + +// SetNillableClientIP sets the "client_ip" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableClientIP(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetClientIP(*v) + } + return _u +} + +// SetSrcHost sets the "src_host" field. +func (_u *PaymentOrderUpdate) SetSrcHost(v string) *PaymentOrderUpdate { + _u.mutation.SetSrcHost(v) + return _u +} + +// SetNillableSrcHost sets the "src_host" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableSrcHost(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetSrcHost(*v) + } + return _u +} + +// SetSrcURL sets the "src_url" field. +func (_u *PaymentOrderUpdate) SetSrcURL(v string) *PaymentOrderUpdate { + _u.mutation.SetSrcURL(v) + return _u +} + +// SetNillableSrcURL sets the "src_url" field if the given value is not nil. +func (_u *PaymentOrderUpdate) SetNillableSrcURL(v *string) *PaymentOrderUpdate { + if v != nil { + _u.SetSrcURL(*v) + } + return _u +} + +// ClearSrcURL clears the value of the "src_url" field. +func (_u *PaymentOrderUpdate) ClearSrcURL() *PaymentOrderUpdate { + _u.mutation.ClearSrcURL() + return _u +} + +// SetUpdatedAt sets the "updated_at" field. +func (_u *PaymentOrderUpdate) SetUpdatedAt(v time.Time) *PaymentOrderUpdate { + _u.mutation.SetUpdatedAt(v) + return _u +} + +// SetUser sets the "user" edge to the User entity. +func (_u *PaymentOrderUpdate) SetUser(v *User) *PaymentOrderUpdate { + return _u.SetUserID(v.ID) +} + +// Mutation returns the PaymentOrderMutation object of the builder. +func (_u *PaymentOrderUpdate) Mutation() *PaymentOrderMutation { + return _u.mutation +} + +// ClearUser clears the "user" edge to the User entity. +func (_u *PaymentOrderUpdate) ClearUser() *PaymentOrderUpdate { + _u.mutation.ClearUser() + return _u +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (_u *PaymentOrderUpdate) Save(ctx context.Context) (int, error) { + _u.defaults() + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *PaymentOrderUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (_u *PaymentOrderUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *PaymentOrderUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_u *PaymentOrderUpdate) defaults() { + if _, ok := _u.mutation.UpdatedAt(); !ok { + v := paymentorder.UpdateDefaultUpdatedAt() + _u.mutation.SetUpdatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *PaymentOrderUpdate) check() error { + if v, ok := _u.mutation.UserEmail(); ok { + if err := paymentorder.UserEmailValidator(v); err != nil { + return &ValidationError{Name: "user_email", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.user_email": %w`, err)} + } + } + if v, ok := _u.mutation.UserName(); ok { + if err := paymentorder.UserNameValidator(v); err != nil { + return &ValidationError{Name: "user_name", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.user_name": %w`, err)} + } + } + if v, ok := _u.mutation.RechargeCode(); ok { + if err := paymentorder.RechargeCodeValidator(v); err != nil { + return &ValidationError{Name: "recharge_code", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.recharge_code": %w`, err)} + } + } + if v, ok := _u.mutation.PaymentType(); ok { + if err := paymentorder.PaymentTypeValidator(v); err != nil { + return &ValidationError{Name: "payment_type", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.payment_type": %w`, err)} + } + } + if v, ok := _u.mutation.PaymentTradeNo(); ok { + if err := paymentorder.PaymentTradeNoValidator(v); err != nil { + return &ValidationError{Name: "payment_trade_no", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.payment_trade_no": %w`, err)} + } + } + if v, ok := _u.mutation.OrderType(); ok { + if err := paymentorder.OrderTypeValidator(v); err != nil { + return &ValidationError{Name: "order_type", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.order_type": %w`, err)} + } + } + if v, ok := _u.mutation.ProviderInstanceID(); ok { + if err := paymentorder.ProviderInstanceIDValidator(v); err != nil { + return &ValidationError{Name: "provider_instance_id", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.provider_instance_id": %w`, err)} + } + } + if v, ok := _u.mutation.Status(); ok { + if err := paymentorder.StatusValidator(v); err != nil { + return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.status": %w`, err)} + } + } + if v, ok := _u.mutation.RefundRequestedBy(); ok { + if err := paymentorder.RefundRequestedByValidator(v); err != nil { + return &ValidationError{Name: "refund_requested_by", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.refund_requested_by": %w`, err)} + } + } + if v, ok := _u.mutation.ClientIP(); ok { + if err := paymentorder.ClientIPValidator(v); err != nil { + return &ValidationError{Name: "client_ip", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.client_ip": %w`, err)} + } + } + if v, ok := _u.mutation.SrcHost(); ok { + if err := paymentorder.SrcHostValidator(v); err != nil { + return &ValidationError{Name: "src_host", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.src_host": %w`, err)} + } + } + if _u.mutation.UserCleared() && len(_u.mutation.UserIDs()) > 0 { + return errors.New(`ent: clearing a required unique edge "PaymentOrder.user"`) + } + return nil +} + +func (_u *PaymentOrderUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(paymentorder.Table, paymentorder.Columns, sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64)) + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.UserEmail(); ok { + _spec.SetField(paymentorder.FieldUserEmail, field.TypeString, value) + } + if value, ok := _u.mutation.UserName(); ok { + _spec.SetField(paymentorder.FieldUserName, field.TypeString, value) + } + if value, ok := _u.mutation.UserNotes(); ok { + _spec.SetField(paymentorder.FieldUserNotes, field.TypeString, value) + } + if _u.mutation.UserNotesCleared() { + _spec.ClearField(paymentorder.FieldUserNotes, field.TypeString) + } + if value, ok := _u.mutation.Amount(); ok { + _spec.SetField(paymentorder.FieldAmount, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedAmount(); ok { + _spec.AddField(paymentorder.FieldAmount, field.TypeFloat64, value) + } + if value, ok := _u.mutation.PayAmount(); ok { + _spec.SetField(paymentorder.FieldPayAmount, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedPayAmount(); ok { + _spec.AddField(paymentorder.FieldPayAmount, field.TypeFloat64, value) + } + if value, ok := _u.mutation.FeeRate(); ok { + _spec.SetField(paymentorder.FieldFeeRate, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedFeeRate(); ok { + _spec.AddField(paymentorder.FieldFeeRate, field.TypeFloat64, value) + } + if value, ok := _u.mutation.RechargeCode(); ok { + _spec.SetField(paymentorder.FieldRechargeCode, field.TypeString, value) + } + if value, ok := _u.mutation.PaymentType(); ok { + _spec.SetField(paymentorder.FieldPaymentType, field.TypeString, value) + } + if value, ok := _u.mutation.PaymentTradeNo(); ok { + _spec.SetField(paymentorder.FieldPaymentTradeNo, field.TypeString, value) + } + if value, ok := _u.mutation.PayURL(); ok { + _spec.SetField(paymentorder.FieldPayURL, field.TypeString, value) + } + if _u.mutation.PayURLCleared() { + _spec.ClearField(paymentorder.FieldPayURL, field.TypeString) + } + if value, ok := _u.mutation.QrCode(); ok { + _spec.SetField(paymentorder.FieldQrCode, field.TypeString, value) + } + if _u.mutation.QrCodeCleared() { + _spec.ClearField(paymentorder.FieldQrCode, field.TypeString) + } + if value, ok := _u.mutation.QrCodeImg(); ok { + _spec.SetField(paymentorder.FieldQrCodeImg, field.TypeString, value) + } + if _u.mutation.QrCodeImgCleared() { + _spec.ClearField(paymentorder.FieldQrCodeImg, field.TypeString) + } + if value, ok := _u.mutation.OrderType(); ok { + _spec.SetField(paymentorder.FieldOrderType, field.TypeString, value) + } + if value, ok := _u.mutation.PlanID(); ok { + _spec.SetField(paymentorder.FieldPlanID, field.TypeInt64, value) + } + if value, ok := _u.mutation.AddedPlanID(); ok { + _spec.AddField(paymentorder.FieldPlanID, field.TypeInt64, value) + } + if _u.mutation.PlanIDCleared() { + _spec.ClearField(paymentorder.FieldPlanID, field.TypeInt64) + } + if value, ok := _u.mutation.SubscriptionGroupID(); ok { + _spec.SetField(paymentorder.FieldSubscriptionGroupID, field.TypeInt64, value) + } + if value, ok := _u.mutation.AddedSubscriptionGroupID(); ok { + _spec.AddField(paymentorder.FieldSubscriptionGroupID, field.TypeInt64, value) + } + if _u.mutation.SubscriptionGroupIDCleared() { + _spec.ClearField(paymentorder.FieldSubscriptionGroupID, field.TypeInt64) + } + if value, ok := _u.mutation.SubscriptionDays(); ok { + _spec.SetField(paymentorder.FieldSubscriptionDays, field.TypeInt, value) + } + if value, ok := _u.mutation.AddedSubscriptionDays(); ok { + _spec.AddField(paymentorder.FieldSubscriptionDays, field.TypeInt, value) + } + if _u.mutation.SubscriptionDaysCleared() { + _spec.ClearField(paymentorder.FieldSubscriptionDays, field.TypeInt) + } + if value, ok := _u.mutation.ProviderInstanceID(); ok { + _spec.SetField(paymentorder.FieldProviderInstanceID, field.TypeString, value) + } + if _u.mutation.ProviderInstanceIDCleared() { + _spec.ClearField(paymentorder.FieldProviderInstanceID, field.TypeString) + } + if value, ok := _u.mutation.Status(); ok { + _spec.SetField(paymentorder.FieldStatus, field.TypeString, value) + } + if value, ok := _u.mutation.RefundAmount(); ok { + _spec.SetField(paymentorder.FieldRefundAmount, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedRefundAmount(); ok { + _spec.AddField(paymentorder.FieldRefundAmount, field.TypeFloat64, value) + } + if value, ok := _u.mutation.RefundReason(); ok { + _spec.SetField(paymentorder.FieldRefundReason, field.TypeString, value) + } + if _u.mutation.RefundReasonCleared() { + _spec.ClearField(paymentorder.FieldRefundReason, field.TypeString) + } + if value, ok := _u.mutation.RefundAt(); ok { + _spec.SetField(paymentorder.FieldRefundAt, field.TypeTime, value) + } + if _u.mutation.RefundAtCleared() { + _spec.ClearField(paymentorder.FieldRefundAt, field.TypeTime) + } + if value, ok := _u.mutation.ForceRefund(); ok { + _spec.SetField(paymentorder.FieldForceRefund, field.TypeBool, value) + } + if value, ok := _u.mutation.RefundRequestedAt(); ok { + _spec.SetField(paymentorder.FieldRefundRequestedAt, field.TypeTime, value) + } + if _u.mutation.RefundRequestedAtCleared() { + _spec.ClearField(paymentorder.FieldRefundRequestedAt, field.TypeTime) + } + if value, ok := _u.mutation.RefundRequestReason(); ok { + _spec.SetField(paymentorder.FieldRefundRequestReason, field.TypeString, value) + } + if _u.mutation.RefundRequestReasonCleared() { + _spec.ClearField(paymentorder.FieldRefundRequestReason, field.TypeString) + } + if value, ok := _u.mutation.RefundRequestedBy(); ok { + _spec.SetField(paymentorder.FieldRefundRequestedBy, field.TypeString, value) + } + if _u.mutation.RefundRequestedByCleared() { + _spec.ClearField(paymentorder.FieldRefundRequestedBy, field.TypeString) + } + if value, ok := _u.mutation.ExpiresAt(); ok { + _spec.SetField(paymentorder.FieldExpiresAt, field.TypeTime, value) + } + if value, ok := _u.mutation.PaidAt(); ok { + _spec.SetField(paymentorder.FieldPaidAt, field.TypeTime, value) + } + if _u.mutation.PaidAtCleared() { + _spec.ClearField(paymentorder.FieldPaidAt, field.TypeTime) + } + if value, ok := _u.mutation.CompletedAt(); ok { + _spec.SetField(paymentorder.FieldCompletedAt, field.TypeTime, value) + } + if _u.mutation.CompletedAtCleared() { + _spec.ClearField(paymentorder.FieldCompletedAt, field.TypeTime) + } + if value, ok := _u.mutation.FailedAt(); ok { + _spec.SetField(paymentorder.FieldFailedAt, field.TypeTime, value) + } + if _u.mutation.FailedAtCleared() { + _spec.ClearField(paymentorder.FieldFailedAt, field.TypeTime) + } + if value, ok := _u.mutation.FailedReason(); ok { + _spec.SetField(paymentorder.FieldFailedReason, field.TypeString, value) + } + if _u.mutation.FailedReasonCleared() { + _spec.ClearField(paymentorder.FieldFailedReason, field.TypeString) + } + if value, ok := _u.mutation.ClientIP(); ok { + _spec.SetField(paymentorder.FieldClientIP, field.TypeString, value) + } + if value, ok := _u.mutation.SrcHost(); ok { + _spec.SetField(paymentorder.FieldSrcHost, field.TypeString, value) + } + if value, ok := _u.mutation.SrcURL(); ok { + _spec.SetField(paymentorder.FieldSrcURL, field.TypeString, value) + } + if _u.mutation.SrcURLCleared() { + _spec.ClearField(paymentorder.FieldSrcURL, field.TypeString) + } + if value, ok := _u.mutation.UpdatedAt(); ok { + _spec.SetField(paymentorder.FieldUpdatedAt, field.TypeTime, value) + } + if _u.mutation.UserCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: paymentorder.UserTable, + Columns: []string{paymentorder.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.UserIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: paymentorder.UserTable, + Columns: []string{paymentorder.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{paymentorder.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + _u.mutation.done = true + return _node, nil +} + +// PaymentOrderUpdateOne is the builder for updating a single PaymentOrder entity. +type PaymentOrderUpdateOne struct { + config + fields []string + hooks []Hook + mutation *PaymentOrderMutation +} + +// SetUserID sets the "user_id" field. +func (_u *PaymentOrderUpdateOne) SetUserID(v int64) *PaymentOrderUpdateOne { + _u.mutation.SetUserID(v) + return _u +} + +// SetNillableUserID sets the "user_id" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableUserID(v *int64) *PaymentOrderUpdateOne { + if v != nil { + _u.SetUserID(*v) + } + return _u +} + +// SetUserEmail sets the "user_email" field. +func (_u *PaymentOrderUpdateOne) SetUserEmail(v string) *PaymentOrderUpdateOne { + _u.mutation.SetUserEmail(v) + return _u +} + +// SetNillableUserEmail sets the "user_email" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableUserEmail(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetUserEmail(*v) + } + return _u +} + +// SetUserName sets the "user_name" field. +func (_u *PaymentOrderUpdateOne) SetUserName(v string) *PaymentOrderUpdateOne { + _u.mutation.SetUserName(v) + return _u +} + +// SetNillableUserName sets the "user_name" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableUserName(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetUserName(*v) + } + return _u +} + +// SetUserNotes sets the "user_notes" field. +func (_u *PaymentOrderUpdateOne) SetUserNotes(v string) *PaymentOrderUpdateOne { + _u.mutation.SetUserNotes(v) + return _u +} + +// SetNillableUserNotes sets the "user_notes" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableUserNotes(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetUserNotes(*v) + } + return _u +} + +// ClearUserNotes clears the value of the "user_notes" field. +func (_u *PaymentOrderUpdateOne) ClearUserNotes() *PaymentOrderUpdateOne { + _u.mutation.ClearUserNotes() + return _u +} + +// SetAmount sets the "amount" field. +func (_u *PaymentOrderUpdateOne) SetAmount(v float64) *PaymentOrderUpdateOne { + _u.mutation.ResetAmount() + _u.mutation.SetAmount(v) + return _u +} + +// SetNillableAmount sets the "amount" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableAmount(v *float64) *PaymentOrderUpdateOne { + if v != nil { + _u.SetAmount(*v) + } + return _u +} + +// AddAmount adds value to the "amount" field. +func (_u *PaymentOrderUpdateOne) AddAmount(v float64) *PaymentOrderUpdateOne { + _u.mutation.AddAmount(v) + return _u +} + +// SetPayAmount sets the "pay_amount" field. +func (_u *PaymentOrderUpdateOne) SetPayAmount(v float64) *PaymentOrderUpdateOne { + _u.mutation.ResetPayAmount() + _u.mutation.SetPayAmount(v) + return _u +} + +// SetNillablePayAmount sets the "pay_amount" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillablePayAmount(v *float64) *PaymentOrderUpdateOne { + if v != nil { + _u.SetPayAmount(*v) + } + return _u +} + +// AddPayAmount adds value to the "pay_amount" field. +func (_u *PaymentOrderUpdateOne) AddPayAmount(v float64) *PaymentOrderUpdateOne { + _u.mutation.AddPayAmount(v) + return _u +} + +// SetFeeRate sets the "fee_rate" field. +func (_u *PaymentOrderUpdateOne) SetFeeRate(v float64) *PaymentOrderUpdateOne { + _u.mutation.ResetFeeRate() + _u.mutation.SetFeeRate(v) + return _u +} + +// SetNillableFeeRate sets the "fee_rate" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableFeeRate(v *float64) *PaymentOrderUpdateOne { + if v != nil { + _u.SetFeeRate(*v) + } + return _u +} + +// AddFeeRate adds value to the "fee_rate" field. +func (_u *PaymentOrderUpdateOne) AddFeeRate(v float64) *PaymentOrderUpdateOne { + _u.mutation.AddFeeRate(v) + return _u +} + +// SetRechargeCode sets the "recharge_code" field. +func (_u *PaymentOrderUpdateOne) SetRechargeCode(v string) *PaymentOrderUpdateOne { + _u.mutation.SetRechargeCode(v) + return _u +} + +// SetNillableRechargeCode sets the "recharge_code" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableRechargeCode(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetRechargeCode(*v) + } + return _u +} + +// SetPaymentType sets the "payment_type" field. +func (_u *PaymentOrderUpdateOne) SetPaymentType(v string) *PaymentOrderUpdateOne { + _u.mutation.SetPaymentType(v) + return _u +} + +// SetNillablePaymentType sets the "payment_type" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillablePaymentType(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetPaymentType(*v) + } + return _u +} + +// SetPaymentTradeNo sets the "payment_trade_no" field. +func (_u *PaymentOrderUpdateOne) SetPaymentTradeNo(v string) *PaymentOrderUpdateOne { + _u.mutation.SetPaymentTradeNo(v) + return _u +} + +// SetNillablePaymentTradeNo sets the "payment_trade_no" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillablePaymentTradeNo(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetPaymentTradeNo(*v) + } + return _u +} + +// SetPayURL sets the "pay_url" field. +func (_u *PaymentOrderUpdateOne) SetPayURL(v string) *PaymentOrderUpdateOne { + _u.mutation.SetPayURL(v) + return _u +} + +// SetNillablePayURL sets the "pay_url" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillablePayURL(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetPayURL(*v) + } + return _u +} + +// ClearPayURL clears the value of the "pay_url" field. +func (_u *PaymentOrderUpdateOne) ClearPayURL() *PaymentOrderUpdateOne { + _u.mutation.ClearPayURL() + return _u +} + +// SetQrCode sets the "qr_code" field. +func (_u *PaymentOrderUpdateOne) SetQrCode(v string) *PaymentOrderUpdateOne { + _u.mutation.SetQrCode(v) + return _u +} + +// SetNillableQrCode sets the "qr_code" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableQrCode(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetQrCode(*v) + } + return _u +} + +// ClearQrCode clears the value of the "qr_code" field. +func (_u *PaymentOrderUpdateOne) ClearQrCode() *PaymentOrderUpdateOne { + _u.mutation.ClearQrCode() + return _u +} + +// SetQrCodeImg sets the "qr_code_img" field. +func (_u *PaymentOrderUpdateOne) SetQrCodeImg(v string) *PaymentOrderUpdateOne { + _u.mutation.SetQrCodeImg(v) + return _u +} + +// SetNillableQrCodeImg sets the "qr_code_img" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableQrCodeImg(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetQrCodeImg(*v) + } + return _u +} + +// ClearQrCodeImg clears the value of the "qr_code_img" field. +func (_u *PaymentOrderUpdateOne) ClearQrCodeImg() *PaymentOrderUpdateOne { + _u.mutation.ClearQrCodeImg() + return _u +} + +// SetOrderType sets the "order_type" field. +func (_u *PaymentOrderUpdateOne) SetOrderType(v string) *PaymentOrderUpdateOne { + _u.mutation.SetOrderType(v) + return _u +} + +// SetNillableOrderType sets the "order_type" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableOrderType(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetOrderType(*v) + } + return _u +} + +// SetPlanID sets the "plan_id" field. +func (_u *PaymentOrderUpdateOne) SetPlanID(v int64) *PaymentOrderUpdateOne { + _u.mutation.ResetPlanID() + _u.mutation.SetPlanID(v) + return _u +} + +// SetNillablePlanID sets the "plan_id" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillablePlanID(v *int64) *PaymentOrderUpdateOne { + if v != nil { + _u.SetPlanID(*v) + } + return _u +} + +// AddPlanID adds value to the "plan_id" field. +func (_u *PaymentOrderUpdateOne) AddPlanID(v int64) *PaymentOrderUpdateOne { + _u.mutation.AddPlanID(v) + return _u +} + +// ClearPlanID clears the value of the "plan_id" field. +func (_u *PaymentOrderUpdateOne) ClearPlanID() *PaymentOrderUpdateOne { + _u.mutation.ClearPlanID() + return _u +} + +// SetSubscriptionGroupID sets the "subscription_group_id" field. +func (_u *PaymentOrderUpdateOne) SetSubscriptionGroupID(v int64) *PaymentOrderUpdateOne { + _u.mutation.ResetSubscriptionGroupID() + _u.mutation.SetSubscriptionGroupID(v) + return _u +} + +// SetNillableSubscriptionGroupID sets the "subscription_group_id" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableSubscriptionGroupID(v *int64) *PaymentOrderUpdateOne { + if v != nil { + _u.SetSubscriptionGroupID(*v) + } + return _u +} + +// AddSubscriptionGroupID adds value to the "subscription_group_id" field. +func (_u *PaymentOrderUpdateOne) AddSubscriptionGroupID(v int64) *PaymentOrderUpdateOne { + _u.mutation.AddSubscriptionGroupID(v) + return _u +} + +// ClearSubscriptionGroupID clears the value of the "subscription_group_id" field. +func (_u *PaymentOrderUpdateOne) ClearSubscriptionGroupID() *PaymentOrderUpdateOne { + _u.mutation.ClearSubscriptionGroupID() + return _u +} + +// SetSubscriptionDays sets the "subscription_days" field. +func (_u *PaymentOrderUpdateOne) SetSubscriptionDays(v int) *PaymentOrderUpdateOne { + _u.mutation.ResetSubscriptionDays() + _u.mutation.SetSubscriptionDays(v) + return _u +} + +// SetNillableSubscriptionDays sets the "subscription_days" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableSubscriptionDays(v *int) *PaymentOrderUpdateOne { + if v != nil { + _u.SetSubscriptionDays(*v) + } + return _u +} + +// AddSubscriptionDays adds value to the "subscription_days" field. +func (_u *PaymentOrderUpdateOne) AddSubscriptionDays(v int) *PaymentOrderUpdateOne { + _u.mutation.AddSubscriptionDays(v) + return _u +} + +// ClearSubscriptionDays clears the value of the "subscription_days" field. +func (_u *PaymentOrderUpdateOne) ClearSubscriptionDays() *PaymentOrderUpdateOne { + _u.mutation.ClearSubscriptionDays() + return _u +} + +// SetProviderInstanceID sets the "provider_instance_id" field. +func (_u *PaymentOrderUpdateOne) SetProviderInstanceID(v string) *PaymentOrderUpdateOne { + _u.mutation.SetProviderInstanceID(v) + return _u +} + +// SetNillableProviderInstanceID sets the "provider_instance_id" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableProviderInstanceID(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetProviderInstanceID(*v) + } + return _u +} + +// ClearProviderInstanceID clears the value of the "provider_instance_id" field. +func (_u *PaymentOrderUpdateOne) ClearProviderInstanceID() *PaymentOrderUpdateOne { + _u.mutation.ClearProviderInstanceID() + return _u +} + +// SetStatus sets the "status" field. +func (_u *PaymentOrderUpdateOne) SetStatus(v string) *PaymentOrderUpdateOne { + _u.mutation.SetStatus(v) + return _u +} + +// SetNillableStatus sets the "status" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableStatus(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetStatus(*v) + } + return _u +} + +// SetRefundAmount sets the "refund_amount" field. +func (_u *PaymentOrderUpdateOne) SetRefundAmount(v float64) *PaymentOrderUpdateOne { + _u.mutation.ResetRefundAmount() + _u.mutation.SetRefundAmount(v) + return _u +} + +// SetNillableRefundAmount sets the "refund_amount" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableRefundAmount(v *float64) *PaymentOrderUpdateOne { + if v != nil { + _u.SetRefundAmount(*v) + } + return _u +} + +// AddRefundAmount adds value to the "refund_amount" field. +func (_u *PaymentOrderUpdateOne) AddRefundAmount(v float64) *PaymentOrderUpdateOne { + _u.mutation.AddRefundAmount(v) + return _u +} + +// SetRefundReason sets the "refund_reason" field. +func (_u *PaymentOrderUpdateOne) SetRefundReason(v string) *PaymentOrderUpdateOne { + _u.mutation.SetRefundReason(v) + return _u +} + +// SetNillableRefundReason sets the "refund_reason" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableRefundReason(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetRefundReason(*v) + } + return _u +} + +// ClearRefundReason clears the value of the "refund_reason" field. +func (_u *PaymentOrderUpdateOne) ClearRefundReason() *PaymentOrderUpdateOne { + _u.mutation.ClearRefundReason() + return _u +} + +// SetRefundAt sets the "refund_at" field. +func (_u *PaymentOrderUpdateOne) SetRefundAt(v time.Time) *PaymentOrderUpdateOne { + _u.mutation.SetRefundAt(v) + return _u +} + +// SetNillableRefundAt sets the "refund_at" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableRefundAt(v *time.Time) *PaymentOrderUpdateOne { + if v != nil { + _u.SetRefundAt(*v) + } + return _u +} + +// ClearRefundAt clears the value of the "refund_at" field. +func (_u *PaymentOrderUpdateOne) ClearRefundAt() *PaymentOrderUpdateOne { + _u.mutation.ClearRefundAt() + return _u +} + +// SetForceRefund sets the "force_refund" field. +func (_u *PaymentOrderUpdateOne) SetForceRefund(v bool) *PaymentOrderUpdateOne { + _u.mutation.SetForceRefund(v) + return _u +} + +// SetNillableForceRefund sets the "force_refund" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableForceRefund(v *bool) *PaymentOrderUpdateOne { + if v != nil { + _u.SetForceRefund(*v) + } + return _u +} + +// SetRefundRequestedAt sets the "refund_requested_at" field. +func (_u *PaymentOrderUpdateOne) SetRefundRequestedAt(v time.Time) *PaymentOrderUpdateOne { + _u.mutation.SetRefundRequestedAt(v) + return _u +} + +// SetNillableRefundRequestedAt sets the "refund_requested_at" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableRefundRequestedAt(v *time.Time) *PaymentOrderUpdateOne { + if v != nil { + _u.SetRefundRequestedAt(*v) + } + return _u +} + +// ClearRefundRequestedAt clears the value of the "refund_requested_at" field. +func (_u *PaymentOrderUpdateOne) ClearRefundRequestedAt() *PaymentOrderUpdateOne { + _u.mutation.ClearRefundRequestedAt() + return _u +} + +// SetRefundRequestReason sets the "refund_request_reason" field. +func (_u *PaymentOrderUpdateOne) SetRefundRequestReason(v string) *PaymentOrderUpdateOne { + _u.mutation.SetRefundRequestReason(v) + return _u +} + +// SetNillableRefundRequestReason sets the "refund_request_reason" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableRefundRequestReason(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetRefundRequestReason(*v) + } + return _u +} + +// ClearRefundRequestReason clears the value of the "refund_request_reason" field. +func (_u *PaymentOrderUpdateOne) ClearRefundRequestReason() *PaymentOrderUpdateOne { + _u.mutation.ClearRefundRequestReason() + return _u +} + +// SetRefundRequestedBy sets the "refund_requested_by" field. +func (_u *PaymentOrderUpdateOne) SetRefundRequestedBy(v string) *PaymentOrderUpdateOne { + _u.mutation.SetRefundRequestedBy(v) + return _u +} + +// SetNillableRefundRequestedBy sets the "refund_requested_by" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableRefundRequestedBy(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetRefundRequestedBy(*v) + } + return _u +} + +// ClearRefundRequestedBy clears the value of the "refund_requested_by" field. +func (_u *PaymentOrderUpdateOne) ClearRefundRequestedBy() *PaymentOrderUpdateOne { + _u.mutation.ClearRefundRequestedBy() + return _u +} + +// SetExpiresAt sets the "expires_at" field. +func (_u *PaymentOrderUpdateOne) SetExpiresAt(v time.Time) *PaymentOrderUpdateOne { + _u.mutation.SetExpiresAt(v) + return _u +} + +// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableExpiresAt(v *time.Time) *PaymentOrderUpdateOne { + if v != nil { + _u.SetExpiresAt(*v) + } + return _u +} + +// SetPaidAt sets the "paid_at" field. +func (_u *PaymentOrderUpdateOne) SetPaidAt(v time.Time) *PaymentOrderUpdateOne { + _u.mutation.SetPaidAt(v) + return _u +} + +// SetNillablePaidAt sets the "paid_at" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillablePaidAt(v *time.Time) *PaymentOrderUpdateOne { + if v != nil { + _u.SetPaidAt(*v) + } + return _u +} + +// ClearPaidAt clears the value of the "paid_at" field. +func (_u *PaymentOrderUpdateOne) ClearPaidAt() *PaymentOrderUpdateOne { + _u.mutation.ClearPaidAt() + return _u +} + +// SetCompletedAt sets the "completed_at" field. +func (_u *PaymentOrderUpdateOne) SetCompletedAt(v time.Time) *PaymentOrderUpdateOne { + _u.mutation.SetCompletedAt(v) + return _u +} + +// SetNillableCompletedAt sets the "completed_at" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableCompletedAt(v *time.Time) *PaymentOrderUpdateOne { + if v != nil { + _u.SetCompletedAt(*v) + } + return _u +} + +// ClearCompletedAt clears the value of the "completed_at" field. +func (_u *PaymentOrderUpdateOne) ClearCompletedAt() *PaymentOrderUpdateOne { + _u.mutation.ClearCompletedAt() + return _u +} + +// SetFailedAt sets the "failed_at" field. +func (_u *PaymentOrderUpdateOne) SetFailedAt(v time.Time) *PaymentOrderUpdateOne { + _u.mutation.SetFailedAt(v) + return _u +} + +// SetNillableFailedAt sets the "failed_at" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableFailedAt(v *time.Time) *PaymentOrderUpdateOne { + if v != nil { + _u.SetFailedAt(*v) + } + return _u +} + +// ClearFailedAt clears the value of the "failed_at" field. +func (_u *PaymentOrderUpdateOne) ClearFailedAt() *PaymentOrderUpdateOne { + _u.mutation.ClearFailedAt() + return _u +} + +// SetFailedReason sets the "failed_reason" field. +func (_u *PaymentOrderUpdateOne) SetFailedReason(v string) *PaymentOrderUpdateOne { + _u.mutation.SetFailedReason(v) + return _u +} + +// SetNillableFailedReason sets the "failed_reason" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableFailedReason(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetFailedReason(*v) + } + return _u +} + +// ClearFailedReason clears the value of the "failed_reason" field. +func (_u *PaymentOrderUpdateOne) ClearFailedReason() *PaymentOrderUpdateOne { + _u.mutation.ClearFailedReason() + return _u +} + +// SetClientIP sets the "client_ip" field. +func (_u *PaymentOrderUpdateOne) SetClientIP(v string) *PaymentOrderUpdateOne { + _u.mutation.SetClientIP(v) + return _u +} + +// SetNillableClientIP sets the "client_ip" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableClientIP(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetClientIP(*v) + } + return _u +} + +// SetSrcHost sets the "src_host" field. +func (_u *PaymentOrderUpdateOne) SetSrcHost(v string) *PaymentOrderUpdateOne { + _u.mutation.SetSrcHost(v) + return _u +} + +// SetNillableSrcHost sets the "src_host" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableSrcHost(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetSrcHost(*v) + } + return _u +} + +// SetSrcURL sets the "src_url" field. +func (_u *PaymentOrderUpdateOne) SetSrcURL(v string) *PaymentOrderUpdateOne { + _u.mutation.SetSrcURL(v) + return _u +} + +// SetNillableSrcURL sets the "src_url" field if the given value is not nil. +func (_u *PaymentOrderUpdateOne) SetNillableSrcURL(v *string) *PaymentOrderUpdateOne { + if v != nil { + _u.SetSrcURL(*v) + } + return _u +} + +// ClearSrcURL clears the value of the "src_url" field. +func (_u *PaymentOrderUpdateOne) ClearSrcURL() *PaymentOrderUpdateOne { + _u.mutation.ClearSrcURL() + return _u +} + +// SetUpdatedAt sets the "updated_at" field. +func (_u *PaymentOrderUpdateOne) SetUpdatedAt(v time.Time) *PaymentOrderUpdateOne { + _u.mutation.SetUpdatedAt(v) + return _u +} + +// SetUser sets the "user" edge to the User entity. +func (_u *PaymentOrderUpdateOne) SetUser(v *User) *PaymentOrderUpdateOne { + return _u.SetUserID(v.ID) +} + +// Mutation returns the PaymentOrderMutation object of the builder. +func (_u *PaymentOrderUpdateOne) Mutation() *PaymentOrderMutation { + return _u.mutation +} + +// ClearUser clears the "user" edge to the User entity. +func (_u *PaymentOrderUpdateOne) ClearUser() *PaymentOrderUpdateOne { + _u.mutation.ClearUser() + return _u +} + +// Where appends a list predicates to the PaymentOrderUpdate builder. +func (_u *PaymentOrderUpdateOne) Where(ps ...predicate.PaymentOrder) *PaymentOrderUpdateOne { + _u.mutation.Where(ps...) + return _u +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (_u *PaymentOrderUpdateOne) Select(field string, fields ...string) *PaymentOrderUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u +} + +// Save executes the query and returns the updated PaymentOrder entity. +func (_u *PaymentOrderUpdateOne) Save(ctx context.Context) (*PaymentOrder, error) { + _u.defaults() + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *PaymentOrderUpdateOne) SaveX(ctx context.Context) *PaymentOrder { + node, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (_u *PaymentOrderUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *PaymentOrderUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_u *PaymentOrderUpdateOne) defaults() { + if _, ok := _u.mutation.UpdatedAt(); !ok { + v := paymentorder.UpdateDefaultUpdatedAt() + _u.mutation.SetUpdatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *PaymentOrderUpdateOne) check() error { + if v, ok := _u.mutation.UserEmail(); ok { + if err := paymentorder.UserEmailValidator(v); err != nil { + return &ValidationError{Name: "user_email", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.user_email": %w`, err)} + } + } + if v, ok := _u.mutation.UserName(); ok { + if err := paymentorder.UserNameValidator(v); err != nil { + return &ValidationError{Name: "user_name", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.user_name": %w`, err)} + } + } + if v, ok := _u.mutation.RechargeCode(); ok { + if err := paymentorder.RechargeCodeValidator(v); err != nil { + return &ValidationError{Name: "recharge_code", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.recharge_code": %w`, err)} + } + } + if v, ok := _u.mutation.PaymentType(); ok { + if err := paymentorder.PaymentTypeValidator(v); err != nil { + return &ValidationError{Name: "payment_type", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.payment_type": %w`, err)} + } + } + if v, ok := _u.mutation.PaymentTradeNo(); ok { + if err := paymentorder.PaymentTradeNoValidator(v); err != nil { + return &ValidationError{Name: "payment_trade_no", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.payment_trade_no": %w`, err)} + } + } + if v, ok := _u.mutation.OrderType(); ok { + if err := paymentorder.OrderTypeValidator(v); err != nil { + return &ValidationError{Name: "order_type", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.order_type": %w`, err)} + } + } + if v, ok := _u.mutation.ProviderInstanceID(); ok { + if err := paymentorder.ProviderInstanceIDValidator(v); err != nil { + return &ValidationError{Name: "provider_instance_id", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.provider_instance_id": %w`, err)} + } + } + if v, ok := _u.mutation.Status(); ok { + if err := paymentorder.StatusValidator(v); err != nil { + return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.status": %w`, err)} + } + } + if v, ok := _u.mutation.RefundRequestedBy(); ok { + if err := paymentorder.RefundRequestedByValidator(v); err != nil { + return &ValidationError{Name: "refund_requested_by", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.refund_requested_by": %w`, err)} + } + } + if v, ok := _u.mutation.ClientIP(); ok { + if err := paymentorder.ClientIPValidator(v); err != nil { + return &ValidationError{Name: "client_ip", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.client_ip": %w`, err)} + } + } + if v, ok := _u.mutation.SrcHost(); ok { + if err := paymentorder.SrcHostValidator(v); err != nil { + return &ValidationError{Name: "src_host", err: fmt.Errorf(`ent: validator failed for field "PaymentOrder.src_host": %w`, err)} + } + } + if _u.mutation.UserCleared() && len(_u.mutation.UserIDs()) > 0 { + return errors.New(`ent: clearing a required unique edge "PaymentOrder.user"`) + } + return nil +} + +func (_u *PaymentOrderUpdateOne) sqlSave(ctx context.Context) (_node *PaymentOrder, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(paymentorder.Table, paymentorder.Columns, sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64)) + id, ok := _u.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "PaymentOrder.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := _u.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, paymentorder.FieldID) + for _, f := range fields { + if !paymentorder.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != paymentorder.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.UserEmail(); ok { + _spec.SetField(paymentorder.FieldUserEmail, field.TypeString, value) + } + if value, ok := _u.mutation.UserName(); ok { + _spec.SetField(paymentorder.FieldUserName, field.TypeString, value) + } + if value, ok := _u.mutation.UserNotes(); ok { + _spec.SetField(paymentorder.FieldUserNotes, field.TypeString, value) + } + if _u.mutation.UserNotesCleared() { + _spec.ClearField(paymentorder.FieldUserNotes, field.TypeString) + } + if value, ok := _u.mutation.Amount(); ok { + _spec.SetField(paymentorder.FieldAmount, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedAmount(); ok { + _spec.AddField(paymentorder.FieldAmount, field.TypeFloat64, value) + } + if value, ok := _u.mutation.PayAmount(); ok { + _spec.SetField(paymentorder.FieldPayAmount, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedPayAmount(); ok { + _spec.AddField(paymentorder.FieldPayAmount, field.TypeFloat64, value) + } + if value, ok := _u.mutation.FeeRate(); ok { + _spec.SetField(paymentorder.FieldFeeRate, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedFeeRate(); ok { + _spec.AddField(paymentorder.FieldFeeRate, field.TypeFloat64, value) + } + if value, ok := _u.mutation.RechargeCode(); ok { + _spec.SetField(paymentorder.FieldRechargeCode, field.TypeString, value) + } + if value, ok := _u.mutation.PaymentType(); ok { + _spec.SetField(paymentorder.FieldPaymentType, field.TypeString, value) + } + if value, ok := _u.mutation.PaymentTradeNo(); ok { + _spec.SetField(paymentorder.FieldPaymentTradeNo, field.TypeString, value) + } + if value, ok := _u.mutation.PayURL(); ok { + _spec.SetField(paymentorder.FieldPayURL, field.TypeString, value) + } + if _u.mutation.PayURLCleared() { + _spec.ClearField(paymentorder.FieldPayURL, field.TypeString) + } + if value, ok := _u.mutation.QrCode(); ok { + _spec.SetField(paymentorder.FieldQrCode, field.TypeString, value) + } + if _u.mutation.QrCodeCleared() { + _spec.ClearField(paymentorder.FieldQrCode, field.TypeString) + } + if value, ok := _u.mutation.QrCodeImg(); ok { + _spec.SetField(paymentorder.FieldQrCodeImg, field.TypeString, value) + } + if _u.mutation.QrCodeImgCleared() { + _spec.ClearField(paymentorder.FieldQrCodeImg, field.TypeString) + } + if value, ok := _u.mutation.OrderType(); ok { + _spec.SetField(paymentorder.FieldOrderType, field.TypeString, value) + } + if value, ok := _u.mutation.PlanID(); ok { + _spec.SetField(paymentorder.FieldPlanID, field.TypeInt64, value) + } + if value, ok := _u.mutation.AddedPlanID(); ok { + _spec.AddField(paymentorder.FieldPlanID, field.TypeInt64, value) + } + if _u.mutation.PlanIDCleared() { + _spec.ClearField(paymentorder.FieldPlanID, field.TypeInt64) + } + if value, ok := _u.mutation.SubscriptionGroupID(); ok { + _spec.SetField(paymentorder.FieldSubscriptionGroupID, field.TypeInt64, value) + } + if value, ok := _u.mutation.AddedSubscriptionGroupID(); ok { + _spec.AddField(paymentorder.FieldSubscriptionGroupID, field.TypeInt64, value) + } + if _u.mutation.SubscriptionGroupIDCleared() { + _spec.ClearField(paymentorder.FieldSubscriptionGroupID, field.TypeInt64) + } + if value, ok := _u.mutation.SubscriptionDays(); ok { + _spec.SetField(paymentorder.FieldSubscriptionDays, field.TypeInt, value) + } + if value, ok := _u.mutation.AddedSubscriptionDays(); ok { + _spec.AddField(paymentorder.FieldSubscriptionDays, field.TypeInt, value) + } + if _u.mutation.SubscriptionDaysCleared() { + _spec.ClearField(paymentorder.FieldSubscriptionDays, field.TypeInt) + } + if value, ok := _u.mutation.ProviderInstanceID(); ok { + _spec.SetField(paymentorder.FieldProviderInstanceID, field.TypeString, value) + } + if _u.mutation.ProviderInstanceIDCleared() { + _spec.ClearField(paymentorder.FieldProviderInstanceID, field.TypeString) + } + if value, ok := _u.mutation.Status(); ok { + _spec.SetField(paymentorder.FieldStatus, field.TypeString, value) + } + if value, ok := _u.mutation.RefundAmount(); ok { + _spec.SetField(paymentorder.FieldRefundAmount, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedRefundAmount(); ok { + _spec.AddField(paymentorder.FieldRefundAmount, field.TypeFloat64, value) + } + if value, ok := _u.mutation.RefundReason(); ok { + _spec.SetField(paymentorder.FieldRefundReason, field.TypeString, value) + } + if _u.mutation.RefundReasonCleared() { + _spec.ClearField(paymentorder.FieldRefundReason, field.TypeString) + } + if value, ok := _u.mutation.RefundAt(); ok { + _spec.SetField(paymentorder.FieldRefundAt, field.TypeTime, value) + } + if _u.mutation.RefundAtCleared() { + _spec.ClearField(paymentorder.FieldRefundAt, field.TypeTime) + } + if value, ok := _u.mutation.ForceRefund(); ok { + _spec.SetField(paymentorder.FieldForceRefund, field.TypeBool, value) + } + if value, ok := _u.mutation.RefundRequestedAt(); ok { + _spec.SetField(paymentorder.FieldRefundRequestedAt, field.TypeTime, value) + } + if _u.mutation.RefundRequestedAtCleared() { + _spec.ClearField(paymentorder.FieldRefundRequestedAt, field.TypeTime) + } + if value, ok := _u.mutation.RefundRequestReason(); ok { + _spec.SetField(paymentorder.FieldRefundRequestReason, field.TypeString, value) + } + if _u.mutation.RefundRequestReasonCleared() { + _spec.ClearField(paymentorder.FieldRefundRequestReason, field.TypeString) + } + if value, ok := _u.mutation.RefundRequestedBy(); ok { + _spec.SetField(paymentorder.FieldRefundRequestedBy, field.TypeString, value) + } + if _u.mutation.RefundRequestedByCleared() { + _spec.ClearField(paymentorder.FieldRefundRequestedBy, field.TypeString) + } + if value, ok := _u.mutation.ExpiresAt(); ok { + _spec.SetField(paymentorder.FieldExpiresAt, field.TypeTime, value) + } + if value, ok := _u.mutation.PaidAt(); ok { + _spec.SetField(paymentorder.FieldPaidAt, field.TypeTime, value) + } + if _u.mutation.PaidAtCleared() { + _spec.ClearField(paymentorder.FieldPaidAt, field.TypeTime) + } + if value, ok := _u.mutation.CompletedAt(); ok { + _spec.SetField(paymentorder.FieldCompletedAt, field.TypeTime, value) + } + if _u.mutation.CompletedAtCleared() { + _spec.ClearField(paymentorder.FieldCompletedAt, field.TypeTime) + } + if value, ok := _u.mutation.FailedAt(); ok { + _spec.SetField(paymentorder.FieldFailedAt, field.TypeTime, value) + } + if _u.mutation.FailedAtCleared() { + _spec.ClearField(paymentorder.FieldFailedAt, field.TypeTime) + } + if value, ok := _u.mutation.FailedReason(); ok { + _spec.SetField(paymentorder.FieldFailedReason, field.TypeString, value) + } + if _u.mutation.FailedReasonCleared() { + _spec.ClearField(paymentorder.FieldFailedReason, field.TypeString) + } + if value, ok := _u.mutation.ClientIP(); ok { + _spec.SetField(paymentorder.FieldClientIP, field.TypeString, value) + } + if value, ok := _u.mutation.SrcHost(); ok { + _spec.SetField(paymentorder.FieldSrcHost, field.TypeString, value) + } + if value, ok := _u.mutation.SrcURL(); ok { + _spec.SetField(paymentorder.FieldSrcURL, field.TypeString, value) + } + if _u.mutation.SrcURLCleared() { + _spec.ClearField(paymentorder.FieldSrcURL, field.TypeString) + } + if value, ok := _u.mutation.UpdatedAt(); ok { + _spec.SetField(paymentorder.FieldUpdatedAt, field.TypeTime, value) + } + if _u.mutation.UserCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: paymentorder.UserTable, + Columns: []string{paymentorder.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.UserIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: paymentorder.UserTable, + Columns: []string{paymentorder.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _node = &PaymentOrder{config: _u.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{paymentorder.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + _u.mutation.done = true + return _node, nil +} diff --git a/backend/ent/paymentproviderinstance.go b/backend/ent/paymentproviderinstance.go new file mode 100644 index 0000000000..4d48a07cd6 --- /dev/null +++ b/backend/ent/paymentproviderinstance.go @@ -0,0 +1,207 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "github.com/Wei-Shaw/sub2api/ent/paymentproviderinstance" +) + +// PaymentProviderInstance is the model entity for the PaymentProviderInstance schema. +type PaymentProviderInstance struct { + config `json:"-"` + // ID of the ent. + ID int64 `json:"id,omitempty"` + // ProviderKey holds the value of the "provider_key" field. + ProviderKey string `json:"provider_key,omitempty"` + // Name holds the value of the "name" field. + Name string `json:"name,omitempty"` + // Config holds the value of the "config" field. + Config string `json:"config,omitempty"` + // SupportedTypes holds the value of the "supported_types" field. + SupportedTypes string `json:"supported_types,omitempty"` + // Enabled holds the value of the "enabled" field. + Enabled bool `json:"enabled,omitempty"` + // SortOrder holds the value of the "sort_order" field. + SortOrder int `json:"sort_order,omitempty"` + // Limits holds the value of the "limits" field. + Limits string `json:"limits,omitempty"` + // RefundEnabled holds the value of the "refund_enabled" field. + RefundEnabled bool `json:"refund_enabled,omitempty"` + // CreatedAt holds the value of the "created_at" field. + CreatedAt time.Time `json:"created_at,omitempty"` + // UpdatedAt holds the value of the "updated_at" field. + UpdatedAt time.Time `json:"updated_at,omitempty"` + selectValues sql.SelectValues +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*PaymentProviderInstance) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case paymentproviderinstance.FieldEnabled, paymentproviderinstance.FieldRefundEnabled: + values[i] = new(sql.NullBool) + case paymentproviderinstance.FieldID, paymentproviderinstance.FieldSortOrder: + values[i] = new(sql.NullInt64) + case paymentproviderinstance.FieldProviderKey, paymentproviderinstance.FieldName, paymentproviderinstance.FieldConfig, paymentproviderinstance.FieldSupportedTypes, paymentproviderinstance.FieldLimits: + values[i] = new(sql.NullString) + case paymentproviderinstance.FieldCreatedAt, paymentproviderinstance.FieldUpdatedAt: + values[i] = new(sql.NullTime) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the PaymentProviderInstance fields. +func (_m *PaymentProviderInstance) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case paymentproviderinstance.FieldID: + value, ok := values[i].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + _m.ID = int64(value.Int64) + case paymentproviderinstance.FieldProviderKey: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field provider_key", values[i]) + } else if value.Valid { + _m.ProviderKey = value.String + } + case paymentproviderinstance.FieldName: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field name", values[i]) + } else if value.Valid { + _m.Name = value.String + } + case paymentproviderinstance.FieldConfig: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field config", values[i]) + } else if value.Valid { + _m.Config = value.String + } + case paymentproviderinstance.FieldSupportedTypes: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field supported_types", values[i]) + } else if value.Valid { + _m.SupportedTypes = value.String + } + case paymentproviderinstance.FieldEnabled: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field enabled", values[i]) + } else if value.Valid { + _m.Enabled = value.Bool + } + case paymentproviderinstance.FieldSortOrder: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field sort_order", values[i]) + } else if value.Valid { + _m.SortOrder = int(value.Int64) + } + case paymentproviderinstance.FieldLimits: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field limits", values[i]) + } else if value.Valid { + _m.Limits = value.String + } + case paymentproviderinstance.FieldRefundEnabled: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field refund_enabled", values[i]) + } else if value.Valid { + _m.RefundEnabled = value.Bool + } + case paymentproviderinstance.FieldCreatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field created_at", values[i]) + } else if value.Valid { + _m.CreatedAt = value.Time + } + case paymentproviderinstance.FieldUpdatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field updated_at", values[i]) + } else if value.Valid { + _m.UpdatedAt = value.Time + } + default: + _m.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the PaymentProviderInstance. +// This includes values selected through modifiers, order, etc. +func (_m *PaymentProviderInstance) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + +// Update returns a builder for updating this PaymentProviderInstance. +// Note that you need to call PaymentProviderInstance.Unwrap() before calling this method if this PaymentProviderInstance +// was returned from a transaction, and the transaction was committed or rolled back. +func (_m *PaymentProviderInstance) Update() *PaymentProviderInstanceUpdateOne { + return NewPaymentProviderInstanceClient(_m.config).UpdateOne(_m) +} + +// Unwrap unwraps the PaymentProviderInstance entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (_m *PaymentProviderInstance) Unwrap() *PaymentProviderInstance { + _tx, ok := _m.config.driver.(*txDriver) + if !ok { + panic("ent: PaymentProviderInstance is not a transactional entity") + } + _m.config.driver = _tx.drv + return _m +} + +// String implements the fmt.Stringer. +func (_m *PaymentProviderInstance) String() string { + var builder strings.Builder + builder.WriteString("PaymentProviderInstance(") + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) + builder.WriteString("provider_key=") + builder.WriteString(_m.ProviderKey) + builder.WriteString(", ") + builder.WriteString("name=") + builder.WriteString(_m.Name) + builder.WriteString(", ") + builder.WriteString("config=") + builder.WriteString(_m.Config) + builder.WriteString(", ") + builder.WriteString("supported_types=") + builder.WriteString(_m.SupportedTypes) + builder.WriteString(", ") + builder.WriteString("enabled=") + builder.WriteString(fmt.Sprintf("%v", _m.Enabled)) + builder.WriteString(", ") + builder.WriteString("sort_order=") + builder.WriteString(fmt.Sprintf("%v", _m.SortOrder)) + builder.WriteString(", ") + builder.WriteString("limits=") + builder.WriteString(_m.Limits) + builder.WriteString(", ") + builder.WriteString("refund_enabled=") + builder.WriteString(fmt.Sprintf("%v", _m.RefundEnabled)) + builder.WriteString(", ") + builder.WriteString("created_at=") + builder.WriteString(_m.CreatedAt.Format(time.ANSIC)) + builder.WriteString(", ") + builder.WriteString("updated_at=") + builder.WriteString(_m.UpdatedAt.Format(time.ANSIC)) + builder.WriteByte(')') + return builder.String() +} + +// PaymentProviderInstances is a parsable slice of PaymentProviderInstance. +type PaymentProviderInstances []*PaymentProviderInstance diff --git a/backend/ent/paymentproviderinstance/paymentproviderinstance.go b/backend/ent/paymentproviderinstance/paymentproviderinstance.go new file mode 100644 index 0000000000..c9fcd78e3c --- /dev/null +++ b/backend/ent/paymentproviderinstance/paymentproviderinstance.go @@ -0,0 +1,148 @@ +// Code generated by ent, DO NOT EDIT. + +package paymentproviderinstance + +import ( + "time" + + "entgo.io/ent/dialect/sql" +) + +const ( + // Label holds the string label denoting the paymentproviderinstance type in the database. + Label = "payment_provider_instance" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldProviderKey holds the string denoting the provider_key field in the database. + FieldProviderKey = "provider_key" + // FieldName holds the string denoting the name field in the database. + FieldName = "name" + // FieldConfig holds the string denoting the config field in the database. + FieldConfig = "config" + // FieldSupportedTypes holds the string denoting the supported_types field in the database. + FieldSupportedTypes = "supported_types" + // FieldEnabled holds the string denoting the enabled field in the database. + FieldEnabled = "enabled" + // FieldSortOrder holds the string denoting the sort_order field in the database. + FieldSortOrder = "sort_order" + // FieldLimits holds the string denoting the limits field in the database. + FieldLimits = "limits" + // FieldRefundEnabled holds the string denoting the refund_enabled field in the database. + FieldRefundEnabled = "refund_enabled" + // FieldCreatedAt holds the string denoting the created_at field in the database. + FieldCreatedAt = "created_at" + // FieldUpdatedAt holds the string denoting the updated_at field in the database. + FieldUpdatedAt = "updated_at" + // Table holds the table name of the paymentproviderinstance in the database. + Table = "payment_provider_instances" +) + +// Columns holds all SQL columns for paymentproviderinstance fields. +var Columns = []string{ + FieldID, + FieldProviderKey, + FieldName, + FieldConfig, + FieldSupportedTypes, + FieldEnabled, + FieldSortOrder, + FieldLimits, + FieldRefundEnabled, + FieldCreatedAt, + FieldUpdatedAt, +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + return false +} + +var ( + // ProviderKeyValidator is a validator for the "provider_key" field. It is called by the builders before save. + ProviderKeyValidator func(string) error + // DefaultName holds the default value on creation for the "name" field. + DefaultName string + // NameValidator is a validator for the "name" field. It is called by the builders before save. + NameValidator func(string) error + // DefaultSupportedTypes holds the default value on creation for the "supported_types" field. + DefaultSupportedTypes string + // SupportedTypesValidator is a validator for the "supported_types" field. It is called by the builders before save. + SupportedTypesValidator func(string) error + // DefaultEnabled holds the default value on creation for the "enabled" field. + DefaultEnabled bool + // DefaultSortOrder holds the default value on creation for the "sort_order" field. + DefaultSortOrder int + // DefaultLimits holds the default value on creation for the "limits" field. + DefaultLimits string + // DefaultRefundEnabled holds the default value on creation for the "refund_enabled" field. + DefaultRefundEnabled bool + // DefaultCreatedAt holds the default value on creation for the "created_at" field. + DefaultCreatedAt func() time.Time + // DefaultUpdatedAt holds the default value on creation for the "updated_at" field. + DefaultUpdatedAt func() time.Time + // UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field. + UpdateDefaultUpdatedAt func() time.Time +) + +// OrderOption defines the ordering options for the PaymentProviderInstance queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByProviderKey orders the results by the provider_key field. +func ByProviderKey(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldProviderKey, opts...).ToFunc() +} + +// ByName orders the results by the name field. +func ByName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldName, opts...).ToFunc() +} + +// ByConfig orders the results by the config field. +func ByConfig(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldConfig, opts...).ToFunc() +} + +// BySupportedTypes orders the results by the supported_types field. +func BySupportedTypes(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldSupportedTypes, opts...).ToFunc() +} + +// ByEnabled orders the results by the enabled field. +func ByEnabled(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldEnabled, opts...).ToFunc() +} + +// BySortOrder orders the results by the sort_order field. +func BySortOrder(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldSortOrder, opts...).ToFunc() +} + +// ByLimits orders the results by the limits field. +func ByLimits(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldLimits, opts...).ToFunc() +} + +// ByRefundEnabled orders the results by the refund_enabled field. +func ByRefundEnabled(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldRefundEnabled, opts...).ToFunc() +} + +// ByCreatedAt orders the results by the created_at field. +func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() +} + +// ByUpdatedAt orders the results by the updated_at field. +func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc() +} diff --git a/backend/ent/paymentproviderinstance/where.go b/backend/ent/paymentproviderinstance/where.go new file mode 100644 index 0000000000..9b6e37b35d --- /dev/null +++ b/backend/ent/paymentproviderinstance/where.go @@ -0,0 +1,585 @@ +// Code generated by ent, DO NOT EDIT. + +package paymentproviderinstance + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "github.com/Wei-Shaw/sub2api/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id int64) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int64) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int64) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int64) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int64) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int64) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int64) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int64) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int64) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLTE(FieldID, id)) +} + +// ProviderKey applies equality check predicate on the "provider_key" field. It's identical to ProviderKeyEQ. +func ProviderKey(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldProviderKey, v)) +} + +// Name applies equality check predicate on the "name" field. It's identical to NameEQ. +func Name(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldName, v)) +} + +// Config applies equality check predicate on the "config" field. It's identical to ConfigEQ. +func Config(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldConfig, v)) +} + +// SupportedTypes applies equality check predicate on the "supported_types" field. It's identical to SupportedTypesEQ. +func SupportedTypes(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldSupportedTypes, v)) +} + +// Enabled applies equality check predicate on the "enabled" field. It's identical to EnabledEQ. +func Enabled(v bool) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldEnabled, v)) +} + +// SortOrder applies equality check predicate on the "sort_order" field. It's identical to SortOrderEQ. +func SortOrder(v int) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldSortOrder, v)) +} + +// Limits applies equality check predicate on the "limits" field. It's identical to LimitsEQ. +func Limits(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldLimits, v)) +} + +// RefundEnabled applies equality check predicate on the "refund_enabled" field. It's identical to RefundEnabledEQ. +func RefundEnabled(v bool) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldRefundEnabled, v)) +} + +// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. +func CreatedAt(v time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldCreatedAt, v)) +} + +// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ. +func UpdatedAt(v time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// ProviderKeyEQ applies the EQ predicate on the "provider_key" field. +func ProviderKeyEQ(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldProviderKey, v)) +} + +// ProviderKeyNEQ applies the NEQ predicate on the "provider_key" field. +func ProviderKeyNEQ(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNEQ(FieldProviderKey, v)) +} + +// ProviderKeyIn applies the In predicate on the "provider_key" field. +func ProviderKeyIn(vs ...string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldIn(FieldProviderKey, vs...)) +} + +// ProviderKeyNotIn applies the NotIn predicate on the "provider_key" field. +func ProviderKeyNotIn(vs ...string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNotIn(FieldProviderKey, vs...)) +} + +// ProviderKeyGT applies the GT predicate on the "provider_key" field. +func ProviderKeyGT(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGT(FieldProviderKey, v)) +} + +// ProviderKeyGTE applies the GTE predicate on the "provider_key" field. +func ProviderKeyGTE(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGTE(FieldProviderKey, v)) +} + +// ProviderKeyLT applies the LT predicate on the "provider_key" field. +func ProviderKeyLT(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLT(FieldProviderKey, v)) +} + +// ProviderKeyLTE applies the LTE predicate on the "provider_key" field. +func ProviderKeyLTE(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLTE(FieldProviderKey, v)) +} + +// ProviderKeyContains applies the Contains predicate on the "provider_key" field. +func ProviderKeyContains(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldContains(FieldProviderKey, v)) +} + +// ProviderKeyHasPrefix applies the HasPrefix predicate on the "provider_key" field. +func ProviderKeyHasPrefix(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldHasPrefix(FieldProviderKey, v)) +} + +// ProviderKeyHasSuffix applies the HasSuffix predicate on the "provider_key" field. +func ProviderKeyHasSuffix(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldHasSuffix(FieldProviderKey, v)) +} + +// ProviderKeyEqualFold applies the EqualFold predicate on the "provider_key" field. +func ProviderKeyEqualFold(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEqualFold(FieldProviderKey, v)) +} + +// ProviderKeyContainsFold applies the ContainsFold predicate on the "provider_key" field. +func ProviderKeyContainsFold(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldContainsFold(FieldProviderKey, v)) +} + +// NameEQ applies the EQ predicate on the "name" field. +func NameEQ(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldName, v)) +} + +// NameNEQ applies the NEQ predicate on the "name" field. +func NameNEQ(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNEQ(FieldName, v)) +} + +// NameIn applies the In predicate on the "name" field. +func NameIn(vs ...string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldIn(FieldName, vs...)) +} + +// NameNotIn applies the NotIn predicate on the "name" field. +func NameNotIn(vs ...string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNotIn(FieldName, vs...)) +} + +// NameGT applies the GT predicate on the "name" field. +func NameGT(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGT(FieldName, v)) +} + +// NameGTE applies the GTE predicate on the "name" field. +func NameGTE(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGTE(FieldName, v)) +} + +// NameLT applies the LT predicate on the "name" field. +func NameLT(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLT(FieldName, v)) +} + +// NameLTE applies the LTE predicate on the "name" field. +func NameLTE(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLTE(FieldName, v)) +} + +// NameContains applies the Contains predicate on the "name" field. +func NameContains(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldContains(FieldName, v)) +} + +// NameHasPrefix applies the HasPrefix predicate on the "name" field. +func NameHasPrefix(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldHasPrefix(FieldName, v)) +} + +// NameHasSuffix applies the HasSuffix predicate on the "name" field. +func NameHasSuffix(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldHasSuffix(FieldName, v)) +} + +// NameEqualFold applies the EqualFold predicate on the "name" field. +func NameEqualFold(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEqualFold(FieldName, v)) +} + +// NameContainsFold applies the ContainsFold predicate on the "name" field. +func NameContainsFold(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldContainsFold(FieldName, v)) +} + +// ConfigEQ applies the EQ predicate on the "config" field. +func ConfigEQ(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldConfig, v)) +} + +// ConfigNEQ applies the NEQ predicate on the "config" field. +func ConfigNEQ(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNEQ(FieldConfig, v)) +} + +// ConfigIn applies the In predicate on the "config" field. +func ConfigIn(vs ...string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldIn(FieldConfig, vs...)) +} + +// ConfigNotIn applies the NotIn predicate on the "config" field. +func ConfigNotIn(vs ...string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNotIn(FieldConfig, vs...)) +} + +// ConfigGT applies the GT predicate on the "config" field. +func ConfigGT(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGT(FieldConfig, v)) +} + +// ConfigGTE applies the GTE predicate on the "config" field. +func ConfigGTE(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGTE(FieldConfig, v)) +} + +// ConfigLT applies the LT predicate on the "config" field. +func ConfigLT(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLT(FieldConfig, v)) +} + +// ConfigLTE applies the LTE predicate on the "config" field. +func ConfigLTE(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLTE(FieldConfig, v)) +} + +// ConfigContains applies the Contains predicate on the "config" field. +func ConfigContains(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldContains(FieldConfig, v)) +} + +// ConfigHasPrefix applies the HasPrefix predicate on the "config" field. +func ConfigHasPrefix(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldHasPrefix(FieldConfig, v)) +} + +// ConfigHasSuffix applies the HasSuffix predicate on the "config" field. +func ConfigHasSuffix(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldHasSuffix(FieldConfig, v)) +} + +// ConfigEqualFold applies the EqualFold predicate on the "config" field. +func ConfigEqualFold(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEqualFold(FieldConfig, v)) +} + +// ConfigContainsFold applies the ContainsFold predicate on the "config" field. +func ConfigContainsFold(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldContainsFold(FieldConfig, v)) +} + +// SupportedTypesEQ applies the EQ predicate on the "supported_types" field. +func SupportedTypesEQ(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldSupportedTypes, v)) +} + +// SupportedTypesNEQ applies the NEQ predicate on the "supported_types" field. +func SupportedTypesNEQ(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNEQ(FieldSupportedTypes, v)) +} + +// SupportedTypesIn applies the In predicate on the "supported_types" field. +func SupportedTypesIn(vs ...string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldIn(FieldSupportedTypes, vs...)) +} + +// SupportedTypesNotIn applies the NotIn predicate on the "supported_types" field. +func SupportedTypesNotIn(vs ...string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNotIn(FieldSupportedTypes, vs...)) +} + +// SupportedTypesGT applies the GT predicate on the "supported_types" field. +func SupportedTypesGT(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGT(FieldSupportedTypes, v)) +} + +// SupportedTypesGTE applies the GTE predicate on the "supported_types" field. +func SupportedTypesGTE(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGTE(FieldSupportedTypes, v)) +} + +// SupportedTypesLT applies the LT predicate on the "supported_types" field. +func SupportedTypesLT(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLT(FieldSupportedTypes, v)) +} + +// SupportedTypesLTE applies the LTE predicate on the "supported_types" field. +func SupportedTypesLTE(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLTE(FieldSupportedTypes, v)) +} + +// SupportedTypesContains applies the Contains predicate on the "supported_types" field. +func SupportedTypesContains(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldContains(FieldSupportedTypes, v)) +} + +// SupportedTypesHasPrefix applies the HasPrefix predicate on the "supported_types" field. +func SupportedTypesHasPrefix(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldHasPrefix(FieldSupportedTypes, v)) +} + +// SupportedTypesHasSuffix applies the HasSuffix predicate on the "supported_types" field. +func SupportedTypesHasSuffix(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldHasSuffix(FieldSupportedTypes, v)) +} + +// SupportedTypesEqualFold applies the EqualFold predicate on the "supported_types" field. +func SupportedTypesEqualFold(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEqualFold(FieldSupportedTypes, v)) +} + +// SupportedTypesContainsFold applies the ContainsFold predicate on the "supported_types" field. +func SupportedTypesContainsFold(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldContainsFold(FieldSupportedTypes, v)) +} + +// EnabledEQ applies the EQ predicate on the "enabled" field. +func EnabledEQ(v bool) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldEnabled, v)) +} + +// EnabledNEQ applies the NEQ predicate on the "enabled" field. +func EnabledNEQ(v bool) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNEQ(FieldEnabled, v)) +} + +// SortOrderEQ applies the EQ predicate on the "sort_order" field. +func SortOrderEQ(v int) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldSortOrder, v)) +} + +// SortOrderNEQ applies the NEQ predicate on the "sort_order" field. +func SortOrderNEQ(v int) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNEQ(FieldSortOrder, v)) +} + +// SortOrderIn applies the In predicate on the "sort_order" field. +func SortOrderIn(vs ...int) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldIn(FieldSortOrder, vs...)) +} + +// SortOrderNotIn applies the NotIn predicate on the "sort_order" field. +func SortOrderNotIn(vs ...int) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNotIn(FieldSortOrder, vs...)) +} + +// SortOrderGT applies the GT predicate on the "sort_order" field. +func SortOrderGT(v int) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGT(FieldSortOrder, v)) +} + +// SortOrderGTE applies the GTE predicate on the "sort_order" field. +func SortOrderGTE(v int) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGTE(FieldSortOrder, v)) +} + +// SortOrderLT applies the LT predicate on the "sort_order" field. +func SortOrderLT(v int) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLT(FieldSortOrder, v)) +} + +// SortOrderLTE applies the LTE predicate on the "sort_order" field. +func SortOrderLTE(v int) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLTE(FieldSortOrder, v)) +} + +// LimitsEQ applies the EQ predicate on the "limits" field. +func LimitsEQ(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldLimits, v)) +} + +// LimitsNEQ applies the NEQ predicate on the "limits" field. +func LimitsNEQ(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNEQ(FieldLimits, v)) +} + +// LimitsIn applies the In predicate on the "limits" field. +func LimitsIn(vs ...string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldIn(FieldLimits, vs...)) +} + +// LimitsNotIn applies the NotIn predicate on the "limits" field. +func LimitsNotIn(vs ...string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNotIn(FieldLimits, vs...)) +} + +// LimitsGT applies the GT predicate on the "limits" field. +func LimitsGT(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGT(FieldLimits, v)) +} + +// LimitsGTE applies the GTE predicate on the "limits" field. +func LimitsGTE(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGTE(FieldLimits, v)) +} + +// LimitsLT applies the LT predicate on the "limits" field. +func LimitsLT(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLT(FieldLimits, v)) +} + +// LimitsLTE applies the LTE predicate on the "limits" field. +func LimitsLTE(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLTE(FieldLimits, v)) +} + +// LimitsContains applies the Contains predicate on the "limits" field. +func LimitsContains(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldContains(FieldLimits, v)) +} + +// LimitsHasPrefix applies the HasPrefix predicate on the "limits" field. +func LimitsHasPrefix(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldHasPrefix(FieldLimits, v)) +} + +// LimitsHasSuffix applies the HasSuffix predicate on the "limits" field. +func LimitsHasSuffix(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldHasSuffix(FieldLimits, v)) +} + +// LimitsEqualFold applies the EqualFold predicate on the "limits" field. +func LimitsEqualFold(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEqualFold(FieldLimits, v)) +} + +// LimitsContainsFold applies the ContainsFold predicate on the "limits" field. +func LimitsContainsFold(v string) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldContainsFold(FieldLimits, v)) +} + +// RefundEnabledEQ applies the EQ predicate on the "refund_enabled" field. +func RefundEnabledEQ(v bool) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldRefundEnabled, v)) +} + +// RefundEnabledNEQ applies the NEQ predicate on the "refund_enabled" field. +func RefundEnabledNEQ(v bool) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNEQ(FieldRefundEnabled, v)) +} + +// CreatedAtEQ applies the EQ predicate on the "created_at" field. +func CreatedAtEQ(v time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldCreatedAt, v)) +} + +// CreatedAtNEQ applies the NEQ predicate on the "created_at" field. +func CreatedAtNEQ(v time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNEQ(FieldCreatedAt, v)) +} + +// CreatedAtIn applies the In predicate on the "created_at" field. +func CreatedAtIn(vs ...time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldIn(FieldCreatedAt, vs...)) +} + +// CreatedAtNotIn applies the NotIn predicate on the "created_at" field. +func CreatedAtNotIn(vs ...time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNotIn(FieldCreatedAt, vs...)) +} + +// CreatedAtGT applies the GT predicate on the "created_at" field. +func CreatedAtGT(v time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGT(FieldCreatedAt, v)) +} + +// CreatedAtGTE applies the GTE predicate on the "created_at" field. +func CreatedAtGTE(v time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGTE(FieldCreatedAt, v)) +} + +// CreatedAtLT applies the LT predicate on the "created_at" field. +func CreatedAtLT(v time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLT(FieldCreatedAt, v)) +} + +// CreatedAtLTE applies the LTE predicate on the "created_at" field. +func CreatedAtLTE(v time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLTE(FieldCreatedAt, v)) +} + +// UpdatedAtEQ applies the EQ predicate on the "updated_at" field. +func UpdatedAtEQ(v time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field. +func UpdatedAtNEQ(v time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtIn applies the In predicate on the "updated_at" field. +func UpdatedAtIn(vs ...time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field. +func UpdatedAtNotIn(vs ...time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldNotIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtGT applies the GT predicate on the "updated_at" field. +func UpdatedAtGT(v time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGT(FieldUpdatedAt, v)) +} + +// UpdatedAtGTE applies the GTE predicate on the "updated_at" field. +func UpdatedAtGTE(v time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldGTE(FieldUpdatedAt, v)) +} + +// UpdatedAtLT applies the LT predicate on the "updated_at" field. +func UpdatedAtLT(v time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLT(FieldUpdatedAt, v)) +} + +// UpdatedAtLTE applies the LTE predicate on the "updated_at" field. +func UpdatedAtLTE(v time.Time) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.FieldLTE(FieldUpdatedAt, v)) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.PaymentProviderInstance) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.PaymentProviderInstance) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.PaymentProviderInstance) predicate.PaymentProviderInstance { + return predicate.PaymentProviderInstance(sql.NotPredicates(p)) +} diff --git a/backend/ent/paymentproviderinstance_create.go b/backend/ent/paymentproviderinstance_create.go new file mode 100644 index 0000000000..207a0b4983 --- /dev/null +++ b/backend/ent/paymentproviderinstance_create.go @@ -0,0 +1,1041 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/paymentproviderinstance" +) + +// PaymentProviderInstanceCreate is the builder for creating a PaymentProviderInstance entity. +type PaymentProviderInstanceCreate struct { + config + mutation *PaymentProviderInstanceMutation + hooks []Hook + conflict []sql.ConflictOption +} + +// SetProviderKey sets the "provider_key" field. +func (_c *PaymentProviderInstanceCreate) SetProviderKey(v string) *PaymentProviderInstanceCreate { + _c.mutation.SetProviderKey(v) + return _c +} + +// SetName sets the "name" field. +func (_c *PaymentProviderInstanceCreate) SetName(v string) *PaymentProviderInstanceCreate { + _c.mutation.SetName(v) + return _c +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (_c *PaymentProviderInstanceCreate) SetNillableName(v *string) *PaymentProviderInstanceCreate { + if v != nil { + _c.SetName(*v) + } + return _c +} + +// SetConfig sets the "config" field. +func (_c *PaymentProviderInstanceCreate) SetConfig(v string) *PaymentProviderInstanceCreate { + _c.mutation.SetConfig(v) + return _c +} + +// SetSupportedTypes sets the "supported_types" field. +func (_c *PaymentProviderInstanceCreate) SetSupportedTypes(v string) *PaymentProviderInstanceCreate { + _c.mutation.SetSupportedTypes(v) + return _c +} + +// SetNillableSupportedTypes sets the "supported_types" field if the given value is not nil. +func (_c *PaymentProviderInstanceCreate) SetNillableSupportedTypes(v *string) *PaymentProviderInstanceCreate { + if v != nil { + _c.SetSupportedTypes(*v) + } + return _c +} + +// SetEnabled sets the "enabled" field. +func (_c *PaymentProviderInstanceCreate) SetEnabled(v bool) *PaymentProviderInstanceCreate { + _c.mutation.SetEnabled(v) + return _c +} + +// SetNillableEnabled sets the "enabled" field if the given value is not nil. +func (_c *PaymentProviderInstanceCreate) SetNillableEnabled(v *bool) *PaymentProviderInstanceCreate { + if v != nil { + _c.SetEnabled(*v) + } + return _c +} + +// SetSortOrder sets the "sort_order" field. +func (_c *PaymentProviderInstanceCreate) SetSortOrder(v int) *PaymentProviderInstanceCreate { + _c.mutation.SetSortOrder(v) + return _c +} + +// SetNillableSortOrder sets the "sort_order" field if the given value is not nil. +func (_c *PaymentProviderInstanceCreate) SetNillableSortOrder(v *int) *PaymentProviderInstanceCreate { + if v != nil { + _c.SetSortOrder(*v) + } + return _c +} + +// SetLimits sets the "limits" field. +func (_c *PaymentProviderInstanceCreate) SetLimits(v string) *PaymentProviderInstanceCreate { + _c.mutation.SetLimits(v) + return _c +} + +// SetNillableLimits sets the "limits" field if the given value is not nil. +func (_c *PaymentProviderInstanceCreate) SetNillableLimits(v *string) *PaymentProviderInstanceCreate { + if v != nil { + _c.SetLimits(*v) + } + return _c +} + +// SetRefundEnabled sets the "refund_enabled" field. +func (_c *PaymentProviderInstanceCreate) SetRefundEnabled(v bool) *PaymentProviderInstanceCreate { + _c.mutation.SetRefundEnabled(v) + return _c +} + +// SetNillableRefundEnabled sets the "refund_enabled" field if the given value is not nil. +func (_c *PaymentProviderInstanceCreate) SetNillableRefundEnabled(v *bool) *PaymentProviderInstanceCreate { + if v != nil { + _c.SetRefundEnabled(*v) + } + return _c +} + +// SetCreatedAt sets the "created_at" field. +func (_c *PaymentProviderInstanceCreate) SetCreatedAt(v time.Time) *PaymentProviderInstanceCreate { + _c.mutation.SetCreatedAt(v) + return _c +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (_c *PaymentProviderInstanceCreate) SetNillableCreatedAt(v *time.Time) *PaymentProviderInstanceCreate { + if v != nil { + _c.SetCreatedAt(*v) + } + return _c +} + +// SetUpdatedAt sets the "updated_at" field. +func (_c *PaymentProviderInstanceCreate) SetUpdatedAt(v time.Time) *PaymentProviderInstanceCreate { + _c.mutation.SetUpdatedAt(v) + return _c +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (_c *PaymentProviderInstanceCreate) SetNillableUpdatedAt(v *time.Time) *PaymentProviderInstanceCreate { + if v != nil { + _c.SetUpdatedAt(*v) + } + return _c +} + +// Mutation returns the PaymentProviderInstanceMutation object of the builder. +func (_c *PaymentProviderInstanceCreate) Mutation() *PaymentProviderInstanceMutation { + return _c.mutation +} + +// Save creates the PaymentProviderInstance in the database. +func (_c *PaymentProviderInstanceCreate) Save(ctx context.Context) (*PaymentProviderInstance, error) { + _c.defaults() + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (_c *PaymentProviderInstanceCreate) SaveX(ctx context.Context) *PaymentProviderInstance { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *PaymentProviderInstanceCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *PaymentProviderInstanceCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_c *PaymentProviderInstanceCreate) defaults() { + if _, ok := _c.mutation.Name(); !ok { + v := paymentproviderinstance.DefaultName + _c.mutation.SetName(v) + } + if _, ok := _c.mutation.SupportedTypes(); !ok { + v := paymentproviderinstance.DefaultSupportedTypes + _c.mutation.SetSupportedTypes(v) + } + if _, ok := _c.mutation.Enabled(); !ok { + v := paymentproviderinstance.DefaultEnabled + _c.mutation.SetEnabled(v) + } + if _, ok := _c.mutation.SortOrder(); !ok { + v := paymentproviderinstance.DefaultSortOrder + _c.mutation.SetSortOrder(v) + } + if _, ok := _c.mutation.Limits(); !ok { + v := paymentproviderinstance.DefaultLimits + _c.mutation.SetLimits(v) + } + if _, ok := _c.mutation.RefundEnabled(); !ok { + v := paymentproviderinstance.DefaultRefundEnabled + _c.mutation.SetRefundEnabled(v) + } + if _, ok := _c.mutation.CreatedAt(); !ok { + v := paymentproviderinstance.DefaultCreatedAt() + _c.mutation.SetCreatedAt(v) + } + if _, ok := _c.mutation.UpdatedAt(); !ok { + v := paymentproviderinstance.DefaultUpdatedAt() + _c.mutation.SetUpdatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_c *PaymentProviderInstanceCreate) check() error { + if _, ok := _c.mutation.ProviderKey(); !ok { + return &ValidationError{Name: "provider_key", err: errors.New(`ent: missing required field "PaymentProviderInstance.provider_key"`)} + } + if v, ok := _c.mutation.ProviderKey(); ok { + if err := paymentproviderinstance.ProviderKeyValidator(v); err != nil { + return &ValidationError{Name: "provider_key", err: fmt.Errorf(`ent: validator failed for field "PaymentProviderInstance.provider_key": %w`, err)} + } + } + if _, ok := _c.mutation.Name(); !ok { + return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "PaymentProviderInstance.name"`)} + } + if v, ok := _c.mutation.Name(); ok { + if err := paymentproviderinstance.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "PaymentProviderInstance.name": %w`, err)} + } + } + if _, ok := _c.mutation.Config(); !ok { + return &ValidationError{Name: "config", err: errors.New(`ent: missing required field "PaymentProviderInstance.config"`)} + } + if _, ok := _c.mutation.SupportedTypes(); !ok { + return &ValidationError{Name: "supported_types", err: errors.New(`ent: missing required field "PaymentProviderInstance.supported_types"`)} + } + if v, ok := _c.mutation.SupportedTypes(); ok { + if err := paymentproviderinstance.SupportedTypesValidator(v); err != nil { + return &ValidationError{Name: "supported_types", err: fmt.Errorf(`ent: validator failed for field "PaymentProviderInstance.supported_types": %w`, err)} + } + } + if _, ok := _c.mutation.Enabled(); !ok { + return &ValidationError{Name: "enabled", err: errors.New(`ent: missing required field "PaymentProviderInstance.enabled"`)} + } + if _, ok := _c.mutation.SortOrder(); !ok { + return &ValidationError{Name: "sort_order", err: errors.New(`ent: missing required field "PaymentProviderInstance.sort_order"`)} + } + if _, ok := _c.mutation.Limits(); !ok { + return &ValidationError{Name: "limits", err: errors.New(`ent: missing required field "PaymentProviderInstance.limits"`)} + } + if _, ok := _c.mutation.RefundEnabled(); !ok { + return &ValidationError{Name: "refund_enabled", err: errors.New(`ent: missing required field "PaymentProviderInstance.refund_enabled"`)} + } + if _, ok := _c.mutation.CreatedAt(); !ok { + return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "PaymentProviderInstance.created_at"`)} + } + if _, ok := _c.mutation.UpdatedAt(); !ok { + return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "PaymentProviderInstance.updated_at"`)} + } + return nil +} + +func (_c *PaymentProviderInstanceCreate) sqlSave(ctx context.Context) (*PaymentProviderInstance, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + id := _spec.ID.Value.(int64) + _node.ID = int64(id) + _c.mutation.id = &_node.ID + _c.mutation.done = true + return _node, nil +} + +func (_c *PaymentProviderInstanceCreate) createSpec() (*PaymentProviderInstance, *sqlgraph.CreateSpec) { + var ( + _node = &PaymentProviderInstance{config: _c.config} + _spec = sqlgraph.NewCreateSpec(paymentproviderinstance.Table, sqlgraph.NewFieldSpec(paymentproviderinstance.FieldID, field.TypeInt64)) + ) + _spec.OnConflict = _c.conflict + if value, ok := _c.mutation.ProviderKey(); ok { + _spec.SetField(paymentproviderinstance.FieldProviderKey, field.TypeString, value) + _node.ProviderKey = value + } + if value, ok := _c.mutation.Name(); ok { + _spec.SetField(paymentproviderinstance.FieldName, field.TypeString, value) + _node.Name = value + } + if value, ok := _c.mutation.Config(); ok { + _spec.SetField(paymentproviderinstance.FieldConfig, field.TypeString, value) + _node.Config = value + } + if value, ok := _c.mutation.SupportedTypes(); ok { + _spec.SetField(paymentproviderinstance.FieldSupportedTypes, field.TypeString, value) + _node.SupportedTypes = value + } + if value, ok := _c.mutation.Enabled(); ok { + _spec.SetField(paymentproviderinstance.FieldEnabled, field.TypeBool, value) + _node.Enabled = value + } + if value, ok := _c.mutation.SortOrder(); ok { + _spec.SetField(paymentproviderinstance.FieldSortOrder, field.TypeInt, value) + _node.SortOrder = value + } + if value, ok := _c.mutation.Limits(); ok { + _spec.SetField(paymentproviderinstance.FieldLimits, field.TypeString, value) + _node.Limits = value + } + if value, ok := _c.mutation.RefundEnabled(); ok { + _spec.SetField(paymentproviderinstance.FieldRefundEnabled, field.TypeBool, value) + _node.RefundEnabled = value + } + if value, ok := _c.mutation.CreatedAt(); ok { + _spec.SetField(paymentproviderinstance.FieldCreatedAt, field.TypeTime, value) + _node.CreatedAt = value + } + if value, ok := _c.mutation.UpdatedAt(); ok { + _spec.SetField(paymentproviderinstance.FieldUpdatedAt, field.TypeTime, value) + _node.UpdatedAt = value + } + return _node, _spec +} + +// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause +// of the `INSERT` statement. For example: +// +// client.PaymentProviderInstance.Create(). +// SetProviderKey(v). +// OnConflict( +// // Update the row with the new values +// // the was proposed for insertion. +// sql.ResolveWithNewValues(), +// ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.PaymentProviderInstanceUpsert) { +// SetProviderKey(v+v). +// }). +// Exec(ctx) +func (_c *PaymentProviderInstanceCreate) OnConflict(opts ...sql.ConflictOption) *PaymentProviderInstanceUpsertOne { + _c.conflict = opts + return &PaymentProviderInstanceUpsertOne{ + create: _c, + } +} + +// OnConflictColumns calls `OnConflict` and configures the columns +// as conflict target. Using this option is equivalent to using: +// +// client.PaymentProviderInstance.Create(). +// OnConflict(sql.ConflictColumns(columns...)). +// Exec(ctx) +func (_c *PaymentProviderInstanceCreate) OnConflictColumns(columns ...string) *PaymentProviderInstanceUpsertOne { + _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) + return &PaymentProviderInstanceUpsertOne{ + create: _c, + } +} + +type ( + // PaymentProviderInstanceUpsertOne is the builder for "upsert"-ing + // one PaymentProviderInstance node. + PaymentProviderInstanceUpsertOne struct { + create *PaymentProviderInstanceCreate + } + + // PaymentProviderInstanceUpsert is the "OnConflict" setter. + PaymentProviderInstanceUpsert struct { + *sql.UpdateSet + } +) + +// SetProviderKey sets the "provider_key" field. +func (u *PaymentProviderInstanceUpsert) SetProviderKey(v string) *PaymentProviderInstanceUpsert { + u.Set(paymentproviderinstance.FieldProviderKey, v) + return u +} + +// UpdateProviderKey sets the "provider_key" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsert) UpdateProviderKey() *PaymentProviderInstanceUpsert { + u.SetExcluded(paymentproviderinstance.FieldProviderKey) + return u +} + +// SetName sets the "name" field. +func (u *PaymentProviderInstanceUpsert) SetName(v string) *PaymentProviderInstanceUpsert { + u.Set(paymentproviderinstance.FieldName, v) + return u +} + +// UpdateName sets the "name" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsert) UpdateName() *PaymentProviderInstanceUpsert { + u.SetExcluded(paymentproviderinstance.FieldName) + return u +} + +// SetConfig sets the "config" field. +func (u *PaymentProviderInstanceUpsert) SetConfig(v string) *PaymentProviderInstanceUpsert { + u.Set(paymentproviderinstance.FieldConfig, v) + return u +} + +// UpdateConfig sets the "config" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsert) UpdateConfig() *PaymentProviderInstanceUpsert { + u.SetExcluded(paymentproviderinstance.FieldConfig) + return u +} + +// SetSupportedTypes sets the "supported_types" field. +func (u *PaymentProviderInstanceUpsert) SetSupportedTypes(v string) *PaymentProviderInstanceUpsert { + u.Set(paymentproviderinstance.FieldSupportedTypes, v) + return u +} + +// UpdateSupportedTypes sets the "supported_types" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsert) UpdateSupportedTypes() *PaymentProviderInstanceUpsert { + u.SetExcluded(paymentproviderinstance.FieldSupportedTypes) + return u +} + +// SetEnabled sets the "enabled" field. +func (u *PaymentProviderInstanceUpsert) SetEnabled(v bool) *PaymentProviderInstanceUpsert { + u.Set(paymentproviderinstance.FieldEnabled, v) + return u +} + +// UpdateEnabled sets the "enabled" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsert) UpdateEnabled() *PaymentProviderInstanceUpsert { + u.SetExcluded(paymentproviderinstance.FieldEnabled) + return u +} + +// SetSortOrder sets the "sort_order" field. +func (u *PaymentProviderInstanceUpsert) SetSortOrder(v int) *PaymentProviderInstanceUpsert { + u.Set(paymentproviderinstance.FieldSortOrder, v) + return u +} + +// UpdateSortOrder sets the "sort_order" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsert) UpdateSortOrder() *PaymentProviderInstanceUpsert { + u.SetExcluded(paymentproviderinstance.FieldSortOrder) + return u +} + +// AddSortOrder adds v to the "sort_order" field. +func (u *PaymentProviderInstanceUpsert) AddSortOrder(v int) *PaymentProviderInstanceUpsert { + u.Add(paymentproviderinstance.FieldSortOrder, v) + return u +} + +// SetLimits sets the "limits" field. +func (u *PaymentProviderInstanceUpsert) SetLimits(v string) *PaymentProviderInstanceUpsert { + u.Set(paymentproviderinstance.FieldLimits, v) + return u +} + +// UpdateLimits sets the "limits" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsert) UpdateLimits() *PaymentProviderInstanceUpsert { + u.SetExcluded(paymentproviderinstance.FieldLimits) + return u +} + +// SetRefundEnabled sets the "refund_enabled" field. +func (u *PaymentProviderInstanceUpsert) SetRefundEnabled(v bool) *PaymentProviderInstanceUpsert { + u.Set(paymentproviderinstance.FieldRefundEnabled, v) + return u +} + +// UpdateRefundEnabled sets the "refund_enabled" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsert) UpdateRefundEnabled() *PaymentProviderInstanceUpsert { + u.SetExcluded(paymentproviderinstance.FieldRefundEnabled) + return u +} + +// SetUpdatedAt sets the "updated_at" field. +func (u *PaymentProviderInstanceUpsert) SetUpdatedAt(v time.Time) *PaymentProviderInstanceUpsert { + u.Set(paymentproviderinstance.FieldUpdatedAt, v) + return u +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsert) UpdateUpdatedAt() *PaymentProviderInstanceUpsert { + u.SetExcluded(paymentproviderinstance.FieldUpdatedAt) + return u +} + +// UpdateNewValues updates the mutable fields using the new values that were set on create. +// Using this option is equivalent to using: +// +// client.PaymentProviderInstance.Create(). +// OnConflict( +// sql.ResolveWithNewValues(), +// ). +// Exec(ctx) +func (u *PaymentProviderInstanceUpsertOne) UpdateNewValues() *PaymentProviderInstanceUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { + if _, exists := u.create.mutation.CreatedAt(); exists { + s.SetIgnore(paymentproviderinstance.FieldCreatedAt) + } + })) + return u +} + +// Ignore sets each column to itself in case of conflict. +// Using this option is equivalent to using: +// +// client.PaymentProviderInstance.Create(). +// OnConflict(sql.ResolveWithIgnore()). +// Exec(ctx) +func (u *PaymentProviderInstanceUpsertOne) Ignore() *PaymentProviderInstanceUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) + return u +} + +// DoNothing configures the conflict_action to `DO NOTHING`. +// Supported only by SQLite and PostgreSQL. +func (u *PaymentProviderInstanceUpsertOne) DoNothing() *PaymentProviderInstanceUpsertOne { + u.create.conflict = append(u.create.conflict, sql.DoNothing()) + return u +} + +// Update allows overriding fields `UPDATE` values. See the PaymentProviderInstanceCreate.OnConflict +// documentation for more info. +func (u *PaymentProviderInstanceUpsertOne) Update(set func(*PaymentProviderInstanceUpsert)) *PaymentProviderInstanceUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { + set(&PaymentProviderInstanceUpsert{UpdateSet: update}) + })) + return u +} + +// SetProviderKey sets the "provider_key" field. +func (u *PaymentProviderInstanceUpsertOne) SetProviderKey(v string) *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetProviderKey(v) + }) +} + +// UpdateProviderKey sets the "provider_key" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertOne) UpdateProviderKey() *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateProviderKey() + }) +} + +// SetName sets the "name" field. +func (u *PaymentProviderInstanceUpsertOne) SetName(v string) *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetName(v) + }) +} + +// UpdateName sets the "name" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertOne) UpdateName() *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateName() + }) +} + +// SetConfig sets the "config" field. +func (u *PaymentProviderInstanceUpsertOne) SetConfig(v string) *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetConfig(v) + }) +} + +// UpdateConfig sets the "config" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertOne) UpdateConfig() *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateConfig() + }) +} + +// SetSupportedTypes sets the "supported_types" field. +func (u *PaymentProviderInstanceUpsertOne) SetSupportedTypes(v string) *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetSupportedTypes(v) + }) +} + +// UpdateSupportedTypes sets the "supported_types" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertOne) UpdateSupportedTypes() *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateSupportedTypes() + }) +} + +// SetEnabled sets the "enabled" field. +func (u *PaymentProviderInstanceUpsertOne) SetEnabled(v bool) *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetEnabled(v) + }) +} + +// UpdateEnabled sets the "enabled" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertOne) UpdateEnabled() *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateEnabled() + }) +} + +// SetSortOrder sets the "sort_order" field. +func (u *PaymentProviderInstanceUpsertOne) SetSortOrder(v int) *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetSortOrder(v) + }) +} + +// AddSortOrder adds v to the "sort_order" field. +func (u *PaymentProviderInstanceUpsertOne) AddSortOrder(v int) *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.AddSortOrder(v) + }) +} + +// UpdateSortOrder sets the "sort_order" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertOne) UpdateSortOrder() *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateSortOrder() + }) +} + +// SetLimits sets the "limits" field. +func (u *PaymentProviderInstanceUpsertOne) SetLimits(v string) *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetLimits(v) + }) +} + +// UpdateLimits sets the "limits" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertOne) UpdateLimits() *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateLimits() + }) +} + +// SetRefundEnabled sets the "refund_enabled" field. +func (u *PaymentProviderInstanceUpsertOne) SetRefundEnabled(v bool) *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetRefundEnabled(v) + }) +} + +// UpdateRefundEnabled sets the "refund_enabled" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertOne) UpdateRefundEnabled() *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateRefundEnabled() + }) +} + +// SetUpdatedAt sets the "updated_at" field. +func (u *PaymentProviderInstanceUpsertOne) SetUpdatedAt(v time.Time) *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetUpdatedAt(v) + }) +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertOne) UpdateUpdatedAt() *PaymentProviderInstanceUpsertOne { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateUpdatedAt() + }) +} + +// Exec executes the query. +func (u *PaymentProviderInstanceUpsertOne) Exec(ctx context.Context) error { + if len(u.create.conflict) == 0 { + return errors.New("ent: missing options for PaymentProviderInstanceCreate.OnConflict") + } + return u.create.Exec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (u *PaymentProviderInstanceUpsertOne) ExecX(ctx context.Context) { + if err := u.create.Exec(ctx); err != nil { + panic(err) + } +} + +// Exec executes the UPSERT query and returns the inserted/updated ID. +func (u *PaymentProviderInstanceUpsertOne) ID(ctx context.Context) (id int64, err error) { + node, err := u.create.Save(ctx) + if err != nil { + return id, err + } + return node.ID, nil +} + +// IDX is like ID, but panics if an error occurs. +func (u *PaymentProviderInstanceUpsertOne) IDX(ctx context.Context) int64 { + id, err := u.ID(ctx) + if err != nil { + panic(err) + } + return id +} + +// PaymentProviderInstanceCreateBulk is the builder for creating many PaymentProviderInstance entities in bulk. +type PaymentProviderInstanceCreateBulk struct { + config + err error + builders []*PaymentProviderInstanceCreate + conflict []sql.ConflictOption +} + +// Save creates the PaymentProviderInstance entities in the database. +func (_c *PaymentProviderInstanceCreateBulk) Save(ctx context.Context) ([]*PaymentProviderInstance, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*PaymentProviderInstance, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { + func(i int, root context.Context) { + builder := _c.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*PaymentProviderInstanceMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.OnConflict = _c.conflict + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + if specs[i].ID.Value != nil { + id := specs[i].ID.Value.(int64) + nodes[i].ID = int64(id) + } + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (_c *PaymentProviderInstanceCreateBulk) SaveX(ctx context.Context) []*PaymentProviderInstance { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *PaymentProviderInstanceCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *PaymentProviderInstanceCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause +// of the `INSERT` statement. For example: +// +// client.PaymentProviderInstance.CreateBulk(builders...). +// OnConflict( +// // Update the row with the new values +// // the was proposed for insertion. +// sql.ResolveWithNewValues(), +// ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.PaymentProviderInstanceUpsert) { +// SetProviderKey(v+v). +// }). +// Exec(ctx) +func (_c *PaymentProviderInstanceCreateBulk) OnConflict(opts ...sql.ConflictOption) *PaymentProviderInstanceUpsertBulk { + _c.conflict = opts + return &PaymentProviderInstanceUpsertBulk{ + create: _c, + } +} + +// OnConflictColumns calls `OnConflict` and configures the columns +// as conflict target. Using this option is equivalent to using: +// +// client.PaymentProviderInstance.Create(). +// OnConflict(sql.ConflictColumns(columns...)). +// Exec(ctx) +func (_c *PaymentProviderInstanceCreateBulk) OnConflictColumns(columns ...string) *PaymentProviderInstanceUpsertBulk { + _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) + return &PaymentProviderInstanceUpsertBulk{ + create: _c, + } +} + +// PaymentProviderInstanceUpsertBulk is the builder for "upsert"-ing +// a bulk of PaymentProviderInstance nodes. +type PaymentProviderInstanceUpsertBulk struct { + create *PaymentProviderInstanceCreateBulk +} + +// UpdateNewValues updates the mutable fields using the new values that +// were set on create. Using this option is equivalent to using: +// +// client.PaymentProviderInstance.Create(). +// OnConflict( +// sql.ResolveWithNewValues(), +// ). +// Exec(ctx) +func (u *PaymentProviderInstanceUpsertBulk) UpdateNewValues() *PaymentProviderInstanceUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { + for _, b := range u.create.builders { + if _, exists := b.mutation.CreatedAt(); exists { + s.SetIgnore(paymentproviderinstance.FieldCreatedAt) + } + } + })) + return u +} + +// Ignore sets each column to itself in case of conflict. +// Using this option is equivalent to using: +// +// client.PaymentProviderInstance.Create(). +// OnConflict(sql.ResolveWithIgnore()). +// Exec(ctx) +func (u *PaymentProviderInstanceUpsertBulk) Ignore() *PaymentProviderInstanceUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) + return u +} + +// DoNothing configures the conflict_action to `DO NOTHING`. +// Supported only by SQLite and PostgreSQL. +func (u *PaymentProviderInstanceUpsertBulk) DoNothing() *PaymentProviderInstanceUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.DoNothing()) + return u +} + +// Update allows overriding fields `UPDATE` values. See the PaymentProviderInstanceCreateBulk.OnConflict +// documentation for more info. +func (u *PaymentProviderInstanceUpsertBulk) Update(set func(*PaymentProviderInstanceUpsert)) *PaymentProviderInstanceUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { + set(&PaymentProviderInstanceUpsert{UpdateSet: update}) + })) + return u +} + +// SetProviderKey sets the "provider_key" field. +func (u *PaymentProviderInstanceUpsertBulk) SetProviderKey(v string) *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetProviderKey(v) + }) +} + +// UpdateProviderKey sets the "provider_key" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertBulk) UpdateProviderKey() *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateProviderKey() + }) +} + +// SetName sets the "name" field. +func (u *PaymentProviderInstanceUpsertBulk) SetName(v string) *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetName(v) + }) +} + +// UpdateName sets the "name" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertBulk) UpdateName() *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateName() + }) +} + +// SetConfig sets the "config" field. +func (u *PaymentProviderInstanceUpsertBulk) SetConfig(v string) *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetConfig(v) + }) +} + +// UpdateConfig sets the "config" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertBulk) UpdateConfig() *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateConfig() + }) +} + +// SetSupportedTypes sets the "supported_types" field. +func (u *PaymentProviderInstanceUpsertBulk) SetSupportedTypes(v string) *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetSupportedTypes(v) + }) +} + +// UpdateSupportedTypes sets the "supported_types" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertBulk) UpdateSupportedTypes() *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateSupportedTypes() + }) +} + +// SetEnabled sets the "enabled" field. +func (u *PaymentProviderInstanceUpsertBulk) SetEnabled(v bool) *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetEnabled(v) + }) +} + +// UpdateEnabled sets the "enabled" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertBulk) UpdateEnabled() *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateEnabled() + }) +} + +// SetSortOrder sets the "sort_order" field. +func (u *PaymentProviderInstanceUpsertBulk) SetSortOrder(v int) *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetSortOrder(v) + }) +} + +// AddSortOrder adds v to the "sort_order" field. +func (u *PaymentProviderInstanceUpsertBulk) AddSortOrder(v int) *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.AddSortOrder(v) + }) +} + +// UpdateSortOrder sets the "sort_order" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertBulk) UpdateSortOrder() *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateSortOrder() + }) +} + +// SetLimits sets the "limits" field. +func (u *PaymentProviderInstanceUpsertBulk) SetLimits(v string) *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetLimits(v) + }) +} + +// UpdateLimits sets the "limits" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertBulk) UpdateLimits() *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateLimits() + }) +} + +// SetRefundEnabled sets the "refund_enabled" field. +func (u *PaymentProviderInstanceUpsertBulk) SetRefundEnabled(v bool) *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetRefundEnabled(v) + }) +} + +// UpdateRefundEnabled sets the "refund_enabled" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertBulk) UpdateRefundEnabled() *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateRefundEnabled() + }) +} + +// SetUpdatedAt sets the "updated_at" field. +func (u *PaymentProviderInstanceUpsertBulk) SetUpdatedAt(v time.Time) *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.SetUpdatedAt(v) + }) +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *PaymentProviderInstanceUpsertBulk) UpdateUpdatedAt() *PaymentProviderInstanceUpsertBulk { + return u.Update(func(s *PaymentProviderInstanceUpsert) { + s.UpdateUpdatedAt() + }) +} + +// Exec executes the query. +func (u *PaymentProviderInstanceUpsertBulk) Exec(ctx context.Context) error { + if u.create.err != nil { + return u.create.err + } + for i, b := range u.create.builders { + if len(b.conflict) != 0 { + return fmt.Errorf("ent: OnConflict was set for builder %d. Set it on the PaymentProviderInstanceCreateBulk instead", i) + } + } + if len(u.create.conflict) == 0 { + return errors.New("ent: missing options for PaymentProviderInstanceCreateBulk.OnConflict") + } + return u.create.Exec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (u *PaymentProviderInstanceUpsertBulk) ExecX(ctx context.Context) { + if err := u.create.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/backend/ent/paymentproviderinstance_delete.go b/backend/ent/paymentproviderinstance_delete.go new file mode 100644 index 0000000000..0cffe73104 --- /dev/null +++ b/backend/ent/paymentproviderinstance_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/paymentproviderinstance" + "github.com/Wei-Shaw/sub2api/ent/predicate" +) + +// PaymentProviderInstanceDelete is the builder for deleting a PaymentProviderInstance entity. +type PaymentProviderInstanceDelete struct { + config + hooks []Hook + mutation *PaymentProviderInstanceMutation +} + +// Where appends a list predicates to the PaymentProviderInstanceDelete builder. +func (_d *PaymentProviderInstanceDelete) Where(ps ...predicate.PaymentProviderInstance) *PaymentProviderInstanceDelete { + _d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (_d *PaymentProviderInstanceDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *PaymentProviderInstanceDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (_d *PaymentProviderInstanceDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(paymentproviderinstance.Table, sqlgraph.NewFieldSpec(paymentproviderinstance.FieldID, field.TypeInt64)) + if ps := _d.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + _d.mutation.done = true + return affected, err +} + +// PaymentProviderInstanceDeleteOne is the builder for deleting a single PaymentProviderInstance entity. +type PaymentProviderInstanceDeleteOne struct { + _d *PaymentProviderInstanceDelete +} + +// Where appends a list predicates to the PaymentProviderInstanceDelete builder. +func (_d *PaymentProviderInstanceDeleteOne) Where(ps ...predicate.PaymentProviderInstance) *PaymentProviderInstanceDeleteOne { + _d._d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query. +func (_d *PaymentProviderInstanceDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{paymentproviderinstance.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *PaymentProviderInstanceDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/backend/ent/paymentproviderinstance_query.go b/backend/ent/paymentproviderinstance_query.go new file mode 100644 index 0000000000..c021208858 --- /dev/null +++ b/backend/ent/paymentproviderinstance_query.go @@ -0,0 +1,564 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "math" + + "entgo.io/ent" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/paymentproviderinstance" + "github.com/Wei-Shaw/sub2api/ent/predicate" +) + +// PaymentProviderInstanceQuery is the builder for querying PaymentProviderInstance entities. +type PaymentProviderInstanceQuery struct { + config + ctx *QueryContext + order []paymentproviderinstance.OrderOption + inters []Interceptor + predicates []predicate.PaymentProviderInstance + modifiers []func(*sql.Selector) + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the PaymentProviderInstanceQuery builder. +func (_q *PaymentProviderInstanceQuery) Where(ps ...predicate.PaymentProviderInstance) *PaymentProviderInstanceQuery { + _q.predicates = append(_q.predicates, ps...) + return _q +} + +// Limit the number of records to be returned by this query. +func (_q *PaymentProviderInstanceQuery) Limit(limit int) *PaymentProviderInstanceQuery { + _q.ctx.Limit = &limit + return _q +} + +// Offset to start from. +func (_q *PaymentProviderInstanceQuery) Offset(offset int) *PaymentProviderInstanceQuery { + _q.ctx.Offset = &offset + return _q +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (_q *PaymentProviderInstanceQuery) Unique(unique bool) *PaymentProviderInstanceQuery { + _q.ctx.Unique = &unique + return _q +} + +// Order specifies how the records should be ordered. +func (_q *PaymentProviderInstanceQuery) Order(o ...paymentproviderinstance.OrderOption) *PaymentProviderInstanceQuery { + _q.order = append(_q.order, o...) + return _q +} + +// First returns the first PaymentProviderInstance entity from the query. +// Returns a *NotFoundError when no PaymentProviderInstance was found. +func (_q *PaymentProviderInstanceQuery) First(ctx context.Context) (*PaymentProviderInstance, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{paymentproviderinstance.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (_q *PaymentProviderInstanceQuery) FirstX(ctx context.Context) *PaymentProviderInstance { + node, err := _q.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first PaymentProviderInstance ID from the query. +// Returns a *NotFoundError when no PaymentProviderInstance ID was found. +func (_q *PaymentProviderInstanceQuery) FirstID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{paymentproviderinstance.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (_q *PaymentProviderInstanceQuery) FirstIDX(ctx context.Context) int64 { + id, err := _q.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single PaymentProviderInstance entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one PaymentProviderInstance entity is found. +// Returns a *NotFoundError when no PaymentProviderInstance entities are found. +func (_q *PaymentProviderInstanceQuery) Only(ctx context.Context) (*PaymentProviderInstance, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{paymentproviderinstance.Label} + default: + return nil, &NotSingularError{paymentproviderinstance.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (_q *PaymentProviderInstanceQuery) OnlyX(ctx context.Context) *PaymentProviderInstance { + node, err := _q.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only PaymentProviderInstance ID in the query. +// Returns a *NotSingularError when more than one PaymentProviderInstance ID is found. +// Returns a *NotFoundError when no entities are found. +func (_q *PaymentProviderInstanceQuery) OnlyID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{paymentproviderinstance.Label} + default: + err = &NotSingularError{paymentproviderinstance.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (_q *PaymentProviderInstanceQuery) OnlyIDX(ctx context.Context) int64 { + id, err := _q.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of PaymentProviderInstances. +func (_q *PaymentProviderInstanceQuery) All(ctx context.Context) ([]*PaymentProviderInstance, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*PaymentProviderInstance, *PaymentProviderInstanceQuery]() + return withInterceptors[[]*PaymentProviderInstance](ctx, _q, qr, _q.inters) +} + +// AllX is like All, but panics if an error occurs. +func (_q *PaymentProviderInstanceQuery) AllX(ctx context.Context) []*PaymentProviderInstance { + nodes, err := _q.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of PaymentProviderInstance IDs. +func (_q *PaymentProviderInstanceQuery) IDs(ctx context.Context) (ids []int64, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(paymentproviderinstance.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (_q *PaymentProviderInstanceQuery) IDsX(ctx context.Context) []int64 { + ids, err := _q.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (_q *PaymentProviderInstanceQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, _q, querierCount[*PaymentProviderInstanceQuery](), _q.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (_q *PaymentProviderInstanceQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (_q *PaymentProviderInstanceQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (_q *PaymentProviderInstanceQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the PaymentProviderInstanceQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (_q *PaymentProviderInstanceQuery) Clone() *PaymentProviderInstanceQuery { + if _q == nil { + return nil + } + return &PaymentProviderInstanceQuery{ + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]paymentproviderinstance.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.PaymentProviderInstance{}, _q.predicates...), + // clone intermediate query. + sql: _q.sql.Clone(), + path: _q.path, + } +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// ProviderKey string `json:"provider_key,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.PaymentProviderInstance.Query(). +// GroupBy(paymentproviderinstance.FieldProviderKey). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (_q *PaymentProviderInstanceQuery) GroupBy(field string, fields ...string) *PaymentProviderInstanceGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &PaymentProviderInstanceGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields + grbuild.label = paymentproviderinstance.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// ProviderKey string `json:"provider_key,omitempty"` +// } +// +// client.PaymentProviderInstance.Query(). +// Select(paymentproviderinstance.FieldProviderKey). +// Scan(ctx, &v) +func (_q *PaymentProviderInstanceQuery) Select(fields ...string) *PaymentProviderInstanceSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &PaymentProviderInstanceSelect{PaymentProviderInstanceQuery: _q} + sbuild.label = paymentproviderinstance.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a PaymentProviderInstanceSelect configured with the given aggregations. +func (_q *PaymentProviderInstanceQuery) Aggregate(fns ...AggregateFunc) *PaymentProviderInstanceSelect { + return _q.Select().Aggregate(fns...) +} + +func (_q *PaymentProviderInstanceQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { + if !paymentproviderinstance.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if _q.path != nil { + prev, err := _q.path(ctx) + if err != nil { + return err + } + _q.sql = prev + } + return nil +} + +func (_q *PaymentProviderInstanceQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*PaymentProviderInstance, error) { + var ( + nodes = []*PaymentProviderInstance{} + _spec = _q.querySpec() + ) + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*PaymentProviderInstance).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &PaymentProviderInstance{config: _q.config} + nodes = append(nodes, node) + return node.assignValues(columns, values) + } + if len(_q.modifiers) > 0 { + _spec.Modifiers = _q.modifiers + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + return nodes, nil +} + +func (_q *PaymentProviderInstanceQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + if len(_q.modifiers) > 0 { + _spec.Modifiers = _q.modifiers + } + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique + } + return sqlgraph.CountNodes(ctx, _q.driver, _spec) +} + +func (_q *PaymentProviderInstanceQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(paymentproviderinstance.Table, paymentproviderinstance.Columns, sqlgraph.NewFieldSpec(paymentproviderinstance.FieldID, field.TypeInt64)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true + } + if fields := _q.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, paymentproviderinstance.FieldID) + for i := range fields { + if fields[i] != paymentproviderinstance.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := _q.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := _q.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := _q.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := _q.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (_q *PaymentProviderInstanceQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) + t1 := builder.Table(paymentproviderinstance.Table) + columns := _q.ctx.Fields + if len(columns) == 0 { + columns = paymentproviderinstance.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if _q.sql != nil { + selector = _q.sql + selector.Select(selector.Columns(columns...)...) + } + if _q.ctx.Unique != nil && *_q.ctx.Unique { + selector.Distinct() + } + for _, m := range _q.modifiers { + m(selector) + } + for _, p := range _q.predicates { + p(selector) + } + for _, p := range _q.order { + p(selector) + } + if offset := _q.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := _q.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// ForUpdate locks the selected rows against concurrent updates, and prevent them from being +// updated, deleted or "selected ... for update" by other sessions, until the transaction is +// either committed or rolled-back. +func (_q *PaymentProviderInstanceQuery) ForUpdate(opts ...sql.LockOption) *PaymentProviderInstanceQuery { + if _q.driver.Dialect() == dialect.Postgres { + _q.Unique(false) + } + _q.modifiers = append(_q.modifiers, func(s *sql.Selector) { + s.ForUpdate(opts...) + }) + return _q +} + +// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock +// on any rows that are read. Other sessions can read the rows, but cannot modify them +// until your transaction commits. +func (_q *PaymentProviderInstanceQuery) ForShare(opts ...sql.LockOption) *PaymentProviderInstanceQuery { + if _q.driver.Dialect() == dialect.Postgres { + _q.Unique(false) + } + _q.modifiers = append(_q.modifiers, func(s *sql.Selector) { + s.ForShare(opts...) + }) + return _q +} + +// PaymentProviderInstanceGroupBy is the group-by builder for PaymentProviderInstance entities. +type PaymentProviderInstanceGroupBy struct { + selector + build *PaymentProviderInstanceQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (_g *PaymentProviderInstanceGroupBy) Aggregate(fns ...AggregateFunc) *PaymentProviderInstanceGroupBy { + _g.fns = append(_g.fns, fns...) + return _g +} + +// Scan applies the selector query and scans the result into the given value. +func (_g *PaymentProviderInstanceGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*PaymentProviderInstanceQuery, *PaymentProviderInstanceGroupBy](ctx, _g.build, _g, _g.build.inters, v) +} + +func (_g *PaymentProviderInstanceGroupBy) sqlScan(ctx context.Context, root *PaymentProviderInstanceQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*_g.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// PaymentProviderInstanceSelect is the builder for selecting fields of PaymentProviderInstance entities. +type PaymentProviderInstanceSelect struct { + *PaymentProviderInstanceQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *PaymentProviderInstanceSelect) Aggregate(fns ...AggregateFunc) *PaymentProviderInstanceSelect { + _s.fns = append(_s.fns, fns...) + return _s +} + +// Scan applies the selector query and scans the result into the given value. +func (_s *PaymentProviderInstanceSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*PaymentProviderInstanceQuery, *PaymentProviderInstanceSelect](ctx, _s.PaymentProviderInstanceQuery, _s, _s.inters, v) +} + +func (_s *PaymentProviderInstanceSelect) sqlScan(ctx context.Context, root *PaymentProviderInstanceQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/backend/ent/paymentproviderinstance_update.go b/backend/ent/paymentproviderinstance_update.go new file mode 100644 index 0000000000..99b5c505b7 --- /dev/null +++ b/backend/ent/paymentproviderinstance_update.go @@ -0,0 +1,550 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/paymentproviderinstance" + "github.com/Wei-Shaw/sub2api/ent/predicate" +) + +// PaymentProviderInstanceUpdate is the builder for updating PaymentProviderInstance entities. +type PaymentProviderInstanceUpdate struct { + config + hooks []Hook + mutation *PaymentProviderInstanceMutation +} + +// Where appends a list predicates to the PaymentProviderInstanceUpdate builder. +func (_u *PaymentProviderInstanceUpdate) Where(ps ...predicate.PaymentProviderInstance) *PaymentProviderInstanceUpdate { + _u.mutation.Where(ps...) + return _u +} + +// SetProviderKey sets the "provider_key" field. +func (_u *PaymentProviderInstanceUpdate) SetProviderKey(v string) *PaymentProviderInstanceUpdate { + _u.mutation.SetProviderKey(v) + return _u +} + +// SetNillableProviderKey sets the "provider_key" field if the given value is not nil. +func (_u *PaymentProviderInstanceUpdate) SetNillableProviderKey(v *string) *PaymentProviderInstanceUpdate { + if v != nil { + _u.SetProviderKey(*v) + } + return _u +} + +// SetName sets the "name" field. +func (_u *PaymentProviderInstanceUpdate) SetName(v string) *PaymentProviderInstanceUpdate { + _u.mutation.SetName(v) + return _u +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (_u *PaymentProviderInstanceUpdate) SetNillableName(v *string) *PaymentProviderInstanceUpdate { + if v != nil { + _u.SetName(*v) + } + return _u +} + +// SetConfig sets the "config" field. +func (_u *PaymentProviderInstanceUpdate) SetConfig(v string) *PaymentProviderInstanceUpdate { + _u.mutation.SetConfig(v) + return _u +} + +// SetNillableConfig sets the "config" field if the given value is not nil. +func (_u *PaymentProviderInstanceUpdate) SetNillableConfig(v *string) *PaymentProviderInstanceUpdate { + if v != nil { + _u.SetConfig(*v) + } + return _u +} + +// SetSupportedTypes sets the "supported_types" field. +func (_u *PaymentProviderInstanceUpdate) SetSupportedTypes(v string) *PaymentProviderInstanceUpdate { + _u.mutation.SetSupportedTypes(v) + return _u +} + +// SetNillableSupportedTypes sets the "supported_types" field if the given value is not nil. +func (_u *PaymentProviderInstanceUpdate) SetNillableSupportedTypes(v *string) *PaymentProviderInstanceUpdate { + if v != nil { + _u.SetSupportedTypes(*v) + } + return _u +} + +// SetEnabled sets the "enabled" field. +func (_u *PaymentProviderInstanceUpdate) SetEnabled(v bool) *PaymentProviderInstanceUpdate { + _u.mutation.SetEnabled(v) + return _u +} + +// SetNillableEnabled sets the "enabled" field if the given value is not nil. +func (_u *PaymentProviderInstanceUpdate) SetNillableEnabled(v *bool) *PaymentProviderInstanceUpdate { + if v != nil { + _u.SetEnabled(*v) + } + return _u +} + +// SetSortOrder sets the "sort_order" field. +func (_u *PaymentProviderInstanceUpdate) SetSortOrder(v int) *PaymentProviderInstanceUpdate { + _u.mutation.ResetSortOrder() + _u.mutation.SetSortOrder(v) + return _u +} + +// SetNillableSortOrder sets the "sort_order" field if the given value is not nil. +func (_u *PaymentProviderInstanceUpdate) SetNillableSortOrder(v *int) *PaymentProviderInstanceUpdate { + if v != nil { + _u.SetSortOrder(*v) + } + return _u +} + +// AddSortOrder adds value to the "sort_order" field. +func (_u *PaymentProviderInstanceUpdate) AddSortOrder(v int) *PaymentProviderInstanceUpdate { + _u.mutation.AddSortOrder(v) + return _u +} + +// SetLimits sets the "limits" field. +func (_u *PaymentProviderInstanceUpdate) SetLimits(v string) *PaymentProviderInstanceUpdate { + _u.mutation.SetLimits(v) + return _u +} + +// SetNillableLimits sets the "limits" field if the given value is not nil. +func (_u *PaymentProviderInstanceUpdate) SetNillableLimits(v *string) *PaymentProviderInstanceUpdate { + if v != nil { + _u.SetLimits(*v) + } + return _u +} + +// SetRefundEnabled sets the "refund_enabled" field. +func (_u *PaymentProviderInstanceUpdate) SetRefundEnabled(v bool) *PaymentProviderInstanceUpdate { + _u.mutation.SetRefundEnabled(v) + return _u +} + +// SetNillableRefundEnabled sets the "refund_enabled" field if the given value is not nil. +func (_u *PaymentProviderInstanceUpdate) SetNillableRefundEnabled(v *bool) *PaymentProviderInstanceUpdate { + if v != nil { + _u.SetRefundEnabled(*v) + } + return _u +} + +// SetUpdatedAt sets the "updated_at" field. +func (_u *PaymentProviderInstanceUpdate) SetUpdatedAt(v time.Time) *PaymentProviderInstanceUpdate { + _u.mutation.SetUpdatedAt(v) + return _u +} + +// Mutation returns the PaymentProviderInstanceMutation object of the builder. +func (_u *PaymentProviderInstanceUpdate) Mutation() *PaymentProviderInstanceMutation { + return _u.mutation +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (_u *PaymentProviderInstanceUpdate) Save(ctx context.Context) (int, error) { + _u.defaults() + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *PaymentProviderInstanceUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (_u *PaymentProviderInstanceUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *PaymentProviderInstanceUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_u *PaymentProviderInstanceUpdate) defaults() { + if _, ok := _u.mutation.UpdatedAt(); !ok { + v := paymentproviderinstance.UpdateDefaultUpdatedAt() + _u.mutation.SetUpdatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *PaymentProviderInstanceUpdate) check() error { + if v, ok := _u.mutation.ProviderKey(); ok { + if err := paymentproviderinstance.ProviderKeyValidator(v); err != nil { + return &ValidationError{Name: "provider_key", err: fmt.Errorf(`ent: validator failed for field "PaymentProviderInstance.provider_key": %w`, err)} + } + } + if v, ok := _u.mutation.Name(); ok { + if err := paymentproviderinstance.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "PaymentProviderInstance.name": %w`, err)} + } + } + if v, ok := _u.mutation.SupportedTypes(); ok { + if err := paymentproviderinstance.SupportedTypesValidator(v); err != nil { + return &ValidationError{Name: "supported_types", err: fmt.Errorf(`ent: validator failed for field "PaymentProviderInstance.supported_types": %w`, err)} + } + } + return nil +} + +func (_u *PaymentProviderInstanceUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(paymentproviderinstance.Table, paymentproviderinstance.Columns, sqlgraph.NewFieldSpec(paymentproviderinstance.FieldID, field.TypeInt64)) + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.ProviderKey(); ok { + _spec.SetField(paymentproviderinstance.FieldProviderKey, field.TypeString, value) + } + if value, ok := _u.mutation.Name(); ok { + _spec.SetField(paymentproviderinstance.FieldName, field.TypeString, value) + } + if value, ok := _u.mutation.Config(); ok { + _spec.SetField(paymentproviderinstance.FieldConfig, field.TypeString, value) + } + if value, ok := _u.mutation.SupportedTypes(); ok { + _spec.SetField(paymentproviderinstance.FieldSupportedTypes, field.TypeString, value) + } + if value, ok := _u.mutation.Enabled(); ok { + _spec.SetField(paymentproviderinstance.FieldEnabled, field.TypeBool, value) + } + if value, ok := _u.mutation.SortOrder(); ok { + _spec.SetField(paymentproviderinstance.FieldSortOrder, field.TypeInt, value) + } + if value, ok := _u.mutation.AddedSortOrder(); ok { + _spec.AddField(paymentproviderinstance.FieldSortOrder, field.TypeInt, value) + } + if value, ok := _u.mutation.Limits(); ok { + _spec.SetField(paymentproviderinstance.FieldLimits, field.TypeString, value) + } + if value, ok := _u.mutation.RefundEnabled(); ok { + _spec.SetField(paymentproviderinstance.FieldRefundEnabled, field.TypeBool, value) + } + if value, ok := _u.mutation.UpdatedAt(); ok { + _spec.SetField(paymentproviderinstance.FieldUpdatedAt, field.TypeTime, value) + } + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{paymentproviderinstance.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + _u.mutation.done = true + return _node, nil +} + +// PaymentProviderInstanceUpdateOne is the builder for updating a single PaymentProviderInstance entity. +type PaymentProviderInstanceUpdateOne struct { + config + fields []string + hooks []Hook + mutation *PaymentProviderInstanceMutation +} + +// SetProviderKey sets the "provider_key" field. +func (_u *PaymentProviderInstanceUpdateOne) SetProviderKey(v string) *PaymentProviderInstanceUpdateOne { + _u.mutation.SetProviderKey(v) + return _u +} + +// SetNillableProviderKey sets the "provider_key" field if the given value is not nil. +func (_u *PaymentProviderInstanceUpdateOne) SetNillableProviderKey(v *string) *PaymentProviderInstanceUpdateOne { + if v != nil { + _u.SetProviderKey(*v) + } + return _u +} + +// SetName sets the "name" field. +func (_u *PaymentProviderInstanceUpdateOne) SetName(v string) *PaymentProviderInstanceUpdateOne { + _u.mutation.SetName(v) + return _u +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (_u *PaymentProviderInstanceUpdateOne) SetNillableName(v *string) *PaymentProviderInstanceUpdateOne { + if v != nil { + _u.SetName(*v) + } + return _u +} + +// SetConfig sets the "config" field. +func (_u *PaymentProviderInstanceUpdateOne) SetConfig(v string) *PaymentProviderInstanceUpdateOne { + _u.mutation.SetConfig(v) + return _u +} + +// SetNillableConfig sets the "config" field if the given value is not nil. +func (_u *PaymentProviderInstanceUpdateOne) SetNillableConfig(v *string) *PaymentProviderInstanceUpdateOne { + if v != nil { + _u.SetConfig(*v) + } + return _u +} + +// SetSupportedTypes sets the "supported_types" field. +func (_u *PaymentProviderInstanceUpdateOne) SetSupportedTypes(v string) *PaymentProviderInstanceUpdateOne { + _u.mutation.SetSupportedTypes(v) + return _u +} + +// SetNillableSupportedTypes sets the "supported_types" field if the given value is not nil. +func (_u *PaymentProviderInstanceUpdateOne) SetNillableSupportedTypes(v *string) *PaymentProviderInstanceUpdateOne { + if v != nil { + _u.SetSupportedTypes(*v) + } + return _u +} + +// SetEnabled sets the "enabled" field. +func (_u *PaymentProviderInstanceUpdateOne) SetEnabled(v bool) *PaymentProviderInstanceUpdateOne { + _u.mutation.SetEnabled(v) + return _u +} + +// SetNillableEnabled sets the "enabled" field if the given value is not nil. +func (_u *PaymentProviderInstanceUpdateOne) SetNillableEnabled(v *bool) *PaymentProviderInstanceUpdateOne { + if v != nil { + _u.SetEnabled(*v) + } + return _u +} + +// SetSortOrder sets the "sort_order" field. +func (_u *PaymentProviderInstanceUpdateOne) SetSortOrder(v int) *PaymentProviderInstanceUpdateOne { + _u.mutation.ResetSortOrder() + _u.mutation.SetSortOrder(v) + return _u +} + +// SetNillableSortOrder sets the "sort_order" field if the given value is not nil. +func (_u *PaymentProviderInstanceUpdateOne) SetNillableSortOrder(v *int) *PaymentProviderInstanceUpdateOne { + if v != nil { + _u.SetSortOrder(*v) + } + return _u +} + +// AddSortOrder adds value to the "sort_order" field. +func (_u *PaymentProviderInstanceUpdateOne) AddSortOrder(v int) *PaymentProviderInstanceUpdateOne { + _u.mutation.AddSortOrder(v) + return _u +} + +// SetLimits sets the "limits" field. +func (_u *PaymentProviderInstanceUpdateOne) SetLimits(v string) *PaymentProviderInstanceUpdateOne { + _u.mutation.SetLimits(v) + return _u +} + +// SetNillableLimits sets the "limits" field if the given value is not nil. +func (_u *PaymentProviderInstanceUpdateOne) SetNillableLimits(v *string) *PaymentProviderInstanceUpdateOne { + if v != nil { + _u.SetLimits(*v) + } + return _u +} + +// SetRefundEnabled sets the "refund_enabled" field. +func (_u *PaymentProviderInstanceUpdateOne) SetRefundEnabled(v bool) *PaymentProviderInstanceUpdateOne { + _u.mutation.SetRefundEnabled(v) + return _u +} + +// SetNillableRefundEnabled sets the "refund_enabled" field if the given value is not nil. +func (_u *PaymentProviderInstanceUpdateOne) SetNillableRefundEnabled(v *bool) *PaymentProviderInstanceUpdateOne { + if v != nil { + _u.SetRefundEnabled(*v) + } + return _u +} + +// SetUpdatedAt sets the "updated_at" field. +func (_u *PaymentProviderInstanceUpdateOne) SetUpdatedAt(v time.Time) *PaymentProviderInstanceUpdateOne { + _u.mutation.SetUpdatedAt(v) + return _u +} + +// Mutation returns the PaymentProviderInstanceMutation object of the builder. +func (_u *PaymentProviderInstanceUpdateOne) Mutation() *PaymentProviderInstanceMutation { + return _u.mutation +} + +// Where appends a list predicates to the PaymentProviderInstanceUpdate builder. +func (_u *PaymentProviderInstanceUpdateOne) Where(ps ...predicate.PaymentProviderInstance) *PaymentProviderInstanceUpdateOne { + _u.mutation.Where(ps...) + return _u +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (_u *PaymentProviderInstanceUpdateOne) Select(field string, fields ...string) *PaymentProviderInstanceUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u +} + +// Save executes the query and returns the updated PaymentProviderInstance entity. +func (_u *PaymentProviderInstanceUpdateOne) Save(ctx context.Context) (*PaymentProviderInstance, error) { + _u.defaults() + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *PaymentProviderInstanceUpdateOne) SaveX(ctx context.Context) *PaymentProviderInstance { + node, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (_u *PaymentProviderInstanceUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *PaymentProviderInstanceUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_u *PaymentProviderInstanceUpdateOne) defaults() { + if _, ok := _u.mutation.UpdatedAt(); !ok { + v := paymentproviderinstance.UpdateDefaultUpdatedAt() + _u.mutation.SetUpdatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *PaymentProviderInstanceUpdateOne) check() error { + if v, ok := _u.mutation.ProviderKey(); ok { + if err := paymentproviderinstance.ProviderKeyValidator(v); err != nil { + return &ValidationError{Name: "provider_key", err: fmt.Errorf(`ent: validator failed for field "PaymentProviderInstance.provider_key": %w`, err)} + } + } + if v, ok := _u.mutation.Name(); ok { + if err := paymentproviderinstance.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "PaymentProviderInstance.name": %w`, err)} + } + } + if v, ok := _u.mutation.SupportedTypes(); ok { + if err := paymentproviderinstance.SupportedTypesValidator(v); err != nil { + return &ValidationError{Name: "supported_types", err: fmt.Errorf(`ent: validator failed for field "PaymentProviderInstance.supported_types": %w`, err)} + } + } + return nil +} + +func (_u *PaymentProviderInstanceUpdateOne) sqlSave(ctx context.Context) (_node *PaymentProviderInstance, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(paymentproviderinstance.Table, paymentproviderinstance.Columns, sqlgraph.NewFieldSpec(paymentproviderinstance.FieldID, field.TypeInt64)) + id, ok := _u.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "PaymentProviderInstance.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := _u.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, paymentproviderinstance.FieldID) + for _, f := range fields { + if !paymentproviderinstance.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != paymentproviderinstance.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.ProviderKey(); ok { + _spec.SetField(paymentproviderinstance.FieldProviderKey, field.TypeString, value) + } + if value, ok := _u.mutation.Name(); ok { + _spec.SetField(paymentproviderinstance.FieldName, field.TypeString, value) + } + if value, ok := _u.mutation.Config(); ok { + _spec.SetField(paymentproviderinstance.FieldConfig, field.TypeString, value) + } + if value, ok := _u.mutation.SupportedTypes(); ok { + _spec.SetField(paymentproviderinstance.FieldSupportedTypes, field.TypeString, value) + } + if value, ok := _u.mutation.Enabled(); ok { + _spec.SetField(paymentproviderinstance.FieldEnabled, field.TypeBool, value) + } + if value, ok := _u.mutation.SortOrder(); ok { + _spec.SetField(paymentproviderinstance.FieldSortOrder, field.TypeInt, value) + } + if value, ok := _u.mutation.AddedSortOrder(); ok { + _spec.AddField(paymentproviderinstance.FieldSortOrder, field.TypeInt, value) + } + if value, ok := _u.mutation.Limits(); ok { + _spec.SetField(paymentproviderinstance.FieldLimits, field.TypeString, value) + } + if value, ok := _u.mutation.RefundEnabled(); ok { + _spec.SetField(paymentproviderinstance.FieldRefundEnabled, field.TypeBool, value) + } + if value, ok := _u.mutation.UpdatedAt(); ok { + _spec.SetField(paymentproviderinstance.FieldUpdatedAt, field.TypeTime, value) + } + _node = &PaymentProviderInstance{config: _u.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{paymentproviderinstance.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + _u.mutation.done = true + return _node, nil +} diff --git a/backend/ent/predicate/predicate.go b/backend/ent/predicate/predicate.go index a652ab3f1b..67f37c755e 100644 --- a/backend/ent/predicate/predicate.go +++ b/backend/ent/predicate/predicate.go @@ -30,6 +30,16 @@ type Group func(*sql.Selector) // IdempotencyRecord is the predicate function for idempotencyrecord builders. type IdempotencyRecord func(*sql.Selector) +// PaymentAuditLog is the predicate function for paymentauditlog builders. +type PaymentAuditLog func(*sql.Selector) + + +// PaymentOrder is the predicate function for paymentorder builders. +type PaymentOrder func(*sql.Selector) + +// PaymentProviderInstance is the predicate function for paymentproviderinstance builders. +type PaymentProviderInstance func(*sql.Selector) + // PromoCode is the predicate function for promocode builders. type PromoCode func(*sql.Selector) @@ -48,6 +58,9 @@ type SecuritySecret func(*sql.Selector) // Setting is the predicate function for setting builders. type Setting func(*sql.Selector) +// SubscriptionPlan is the predicate function for subscriptionplan builders. +type SubscriptionPlan func(*sql.Selector) + // TLSFingerprintProfile is the predicate function for tlsfingerprintprofile builders. type TLSFingerprintProfile func(*sql.Selector) diff --git a/backend/ent/runtime/runtime.go b/backend/ent/runtime/runtime.go index 803b7bc24b..1ce0c4b438 100644 --- a/backend/ent/runtime/runtime.go +++ b/backend/ent/runtime/runtime.go @@ -13,6 +13,9 @@ import ( "github.com/Wei-Shaw/sub2api/ent/errorpassthroughrule" "github.com/Wei-Shaw/sub2api/ent/group" "github.com/Wei-Shaw/sub2api/ent/idempotencyrecord" + "github.com/Wei-Shaw/sub2api/ent/paymentauditlog" + "github.com/Wei-Shaw/sub2api/ent/paymentorder" + "github.com/Wei-Shaw/sub2api/ent/paymentproviderinstance" "github.com/Wei-Shaw/sub2api/ent/promocode" "github.com/Wei-Shaw/sub2api/ent/promocodeusage" "github.com/Wei-Shaw/sub2api/ent/proxy" @@ -20,6 +23,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/schema" "github.com/Wei-Shaw/sub2api/ent/securitysecret" "github.com/Wei-Shaw/sub2api/ent/setting" + "github.com/Wei-Shaw/sub2api/ent/subscriptionplan" "github.com/Wei-Shaw/sub2api/ent/tlsfingerprintprofile" "github.com/Wei-Shaw/sub2api/ent/usagecleanuptask" "github.com/Wei-Shaw/sub2api/ent/usagelog" @@ -503,6 +507,160 @@ func init() { idempotencyrecordDescErrorReason := idempotencyrecordFields[6].Descriptor() // idempotencyrecord.ErrorReasonValidator is a validator for the "error_reason" field. It is called by the builders before save. idempotencyrecord.ErrorReasonValidator = idempotencyrecordDescErrorReason.Validators[0].(func(string) error) + paymentauditlogFields := schema.PaymentAuditLog{}.Fields() + _ = paymentauditlogFields + // paymentauditlogDescOrderID is the schema descriptor for order_id field. + paymentauditlogDescOrderID := paymentauditlogFields[0].Descriptor() + // paymentauditlog.OrderIDValidator is a validator for the "order_id" field. It is called by the builders before save. + paymentauditlog.OrderIDValidator = paymentauditlogDescOrderID.Validators[0].(func(string) error) + // paymentauditlogDescAction is the schema descriptor for action field. + paymentauditlogDescAction := paymentauditlogFields[1].Descriptor() + // paymentauditlog.ActionValidator is a validator for the "action" field. It is called by the builders before save. + paymentauditlog.ActionValidator = paymentauditlogDescAction.Validators[0].(func(string) error) + // paymentauditlogDescDetail is the schema descriptor for detail field. + paymentauditlogDescDetail := paymentauditlogFields[2].Descriptor() + // paymentauditlog.DefaultDetail holds the default value on creation for the detail field. + paymentauditlog.DefaultDetail = paymentauditlogDescDetail.Default.(string) + // paymentauditlogDescOperator is the schema descriptor for operator field. + paymentauditlogDescOperator := paymentauditlogFields[3].Descriptor() + // paymentauditlog.DefaultOperator holds the default value on creation for the operator field. + paymentauditlog.DefaultOperator = paymentauditlogDescOperator.Default.(string) + // paymentauditlog.OperatorValidator is a validator for the "operator" field. It is called by the builders before save. + paymentauditlog.OperatorValidator = paymentauditlogDescOperator.Validators[0].(func(string) error) + // paymentauditlogDescCreatedAt is the schema descriptor for created_at field. + paymentauditlogDescCreatedAt := paymentauditlogFields[4].Descriptor() + // paymentauditlog.DefaultCreatedAt holds the default value on creation for the created_at field. + paymentauditlog.DefaultCreatedAt = paymentauditlogDescCreatedAt.Default.(func() time.Time) + paymentorderFields := schema.PaymentOrder{}.Fields() + _ = paymentorderFields + // paymentorderDescUserEmail is the schema descriptor for user_email field. + paymentorderDescUserEmail := paymentorderFields[1].Descriptor() + // paymentorder.UserEmailValidator is a validator for the "user_email" field. It is called by the builders before save. + paymentorder.UserEmailValidator = paymentorderDescUserEmail.Validators[0].(func(string) error) + // paymentorderDescUserName is the schema descriptor for user_name field. + paymentorderDescUserName := paymentorderFields[2].Descriptor() + // paymentorder.UserNameValidator is a validator for the "user_name" field. It is called by the builders before save. + paymentorder.UserNameValidator = paymentorderDescUserName.Validators[0].(func(string) error) + // paymentorderDescFeeRate is the schema descriptor for fee_rate field. + paymentorderDescFeeRate := paymentorderFields[6].Descriptor() + // paymentorder.DefaultFeeRate holds the default value on creation for the fee_rate field. + paymentorder.DefaultFeeRate = paymentorderDescFeeRate.Default.(float64) + // paymentorderDescRechargeCode is the schema descriptor for recharge_code field. + paymentorderDescRechargeCode := paymentorderFields[7].Descriptor() + // paymentorder.RechargeCodeValidator is a validator for the "recharge_code" field. It is called by the builders before save. + paymentorder.RechargeCodeValidator = paymentorderDescRechargeCode.Validators[0].(func(string) error) + // paymentorderDescPaymentType is the schema descriptor for payment_type field. + paymentorderDescPaymentType := paymentorderFields[8].Descriptor() + // paymentorder.PaymentTypeValidator is a validator for the "payment_type" field. It is called by the builders before save. + paymentorder.PaymentTypeValidator = paymentorderDescPaymentType.Validators[0].(func(string) error) + // paymentorderDescPaymentTradeNo is the schema descriptor for payment_trade_no field. + paymentorderDescPaymentTradeNo := paymentorderFields[9].Descriptor() + // paymentorder.PaymentTradeNoValidator is a validator for the "payment_trade_no" field. It is called by the builders before save. + paymentorder.PaymentTradeNoValidator = paymentorderDescPaymentTradeNo.Validators[0].(func(string) error) + // paymentorderDescOrderType is the schema descriptor for order_type field. + paymentorderDescOrderType := paymentorderFields[13].Descriptor() + // paymentorder.DefaultOrderType holds the default value on creation for the order_type field. + paymentorder.DefaultOrderType = paymentorderDescOrderType.Default.(string) + // paymentorder.OrderTypeValidator is a validator for the "order_type" field. It is called by the builders before save. + paymentorder.OrderTypeValidator = paymentorderDescOrderType.Validators[0].(func(string) error) + // paymentorderDescProviderInstanceID is the schema descriptor for provider_instance_id field. + paymentorderDescProviderInstanceID := paymentorderFields[17].Descriptor() + // paymentorder.ProviderInstanceIDValidator is a validator for the "provider_instance_id" field. It is called by the builders before save. + paymentorder.ProviderInstanceIDValidator = paymentorderDescProviderInstanceID.Validators[0].(func(string) error) + // paymentorderDescStatus is the schema descriptor for status field. + paymentorderDescStatus := paymentorderFields[18].Descriptor() + // paymentorder.DefaultStatus holds the default value on creation for the status field. + paymentorder.DefaultStatus = paymentorderDescStatus.Default.(string) + // paymentorder.StatusValidator is a validator for the "status" field. It is called by the builders before save. + paymentorder.StatusValidator = paymentorderDescStatus.Validators[0].(func(string) error) + // paymentorderDescRefundAmount is the schema descriptor for refund_amount field. + paymentorderDescRefundAmount := paymentorderFields[19].Descriptor() + // paymentorder.DefaultRefundAmount holds the default value on creation for the refund_amount field. + paymentorder.DefaultRefundAmount = paymentorderDescRefundAmount.Default.(float64) + // paymentorderDescForceRefund is the schema descriptor for force_refund field. + paymentorderDescForceRefund := paymentorderFields[22].Descriptor() + // paymentorder.DefaultForceRefund holds the default value on creation for the force_refund field. + paymentorder.DefaultForceRefund = paymentorderDescForceRefund.Default.(bool) + // paymentorderDescRefundRequestedBy is the schema descriptor for refund_requested_by field. + paymentorderDescRefundRequestedBy := paymentorderFields[25].Descriptor() + // paymentorder.RefundRequestedByValidator is a validator for the "refund_requested_by" field. It is called by the builders before save. + paymentorder.RefundRequestedByValidator = paymentorderDescRefundRequestedBy.Validators[0].(func(string) error) + // paymentorderDescClientIP is the schema descriptor for client_ip field. + paymentorderDescClientIP := paymentorderFields[31].Descriptor() + // paymentorder.ClientIPValidator is a validator for the "client_ip" field. It is called by the builders before save. + paymentorder.ClientIPValidator = paymentorderDescClientIP.Validators[0].(func(string) error) + // paymentorderDescSrcHost is the schema descriptor for src_host field. + paymentorderDescSrcHost := paymentorderFields[32].Descriptor() + // paymentorder.SrcHostValidator is a validator for the "src_host" field. It is called by the builders before save. + paymentorder.SrcHostValidator = paymentorderDescSrcHost.Validators[0].(func(string) error) + // paymentorderDescCreatedAt is the schema descriptor for created_at field. + paymentorderDescCreatedAt := paymentorderFields[34].Descriptor() + // paymentorder.DefaultCreatedAt holds the default value on creation for the created_at field. + paymentorder.DefaultCreatedAt = paymentorderDescCreatedAt.Default.(func() time.Time) + // paymentorderDescUpdatedAt is the schema descriptor for updated_at field. + paymentorderDescUpdatedAt := paymentorderFields[35].Descriptor() + // paymentorder.DefaultUpdatedAt holds the default value on creation for the updated_at field. + paymentorder.DefaultUpdatedAt = paymentorderDescUpdatedAt.Default.(func() time.Time) + // paymentorder.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field. + paymentorder.UpdateDefaultUpdatedAt = paymentorderDescUpdatedAt.UpdateDefault.(func() time.Time) + paymentproviderinstanceFields := schema.PaymentProviderInstance{}.Fields() + _ = paymentproviderinstanceFields + // paymentproviderinstanceDescProviderKey is the schema descriptor for provider_key field. + paymentproviderinstanceDescProviderKey := paymentproviderinstanceFields[0].Descriptor() + // paymentproviderinstance.ProviderKeyValidator is a validator for the "provider_key" field. It is called by the builders before save. + paymentproviderinstance.ProviderKeyValidator = func() func(string) error { + validators := paymentproviderinstanceDescProviderKey.Validators + fns := [...]func(string) error{ + validators[0].(func(string) error), + validators[1].(func(string) error), + } + return func(provider_key string) error { + for _, fn := range fns { + if err := fn(provider_key); err != nil { + return err + } + } + return nil + } + }() + // paymentproviderinstanceDescName is the schema descriptor for name field. + paymentproviderinstanceDescName := paymentproviderinstanceFields[1].Descriptor() + // paymentproviderinstance.DefaultName holds the default value on creation for the name field. + paymentproviderinstance.DefaultName = paymentproviderinstanceDescName.Default.(string) + // paymentproviderinstance.NameValidator is a validator for the "name" field. It is called by the builders before save. + paymentproviderinstance.NameValidator = paymentproviderinstanceDescName.Validators[0].(func(string) error) + // paymentproviderinstanceDescSupportedTypes is the schema descriptor for supported_types field. + paymentproviderinstanceDescSupportedTypes := paymentproviderinstanceFields[3].Descriptor() + // paymentproviderinstance.DefaultSupportedTypes holds the default value on creation for the supported_types field. + paymentproviderinstance.DefaultSupportedTypes = paymentproviderinstanceDescSupportedTypes.Default.(string) + // paymentproviderinstance.SupportedTypesValidator is a validator for the "supported_types" field. It is called by the builders before save. + paymentproviderinstance.SupportedTypesValidator = paymentproviderinstanceDescSupportedTypes.Validators[0].(func(string) error) + // paymentproviderinstanceDescEnabled is the schema descriptor for enabled field. + paymentproviderinstanceDescEnabled := paymentproviderinstanceFields[4].Descriptor() + // paymentproviderinstance.DefaultEnabled holds the default value on creation for the enabled field. + paymentproviderinstance.DefaultEnabled = paymentproviderinstanceDescEnabled.Default.(bool) + // paymentproviderinstanceDescSortOrder is the schema descriptor for sort_order field. + paymentproviderinstanceDescSortOrder := paymentproviderinstanceFields[5].Descriptor() + // paymentproviderinstance.DefaultSortOrder holds the default value on creation for the sort_order field. + paymentproviderinstance.DefaultSortOrder = paymentproviderinstanceDescSortOrder.Default.(int) + // paymentproviderinstanceDescLimits is the schema descriptor for limits field. + paymentproviderinstanceDescLimits := paymentproviderinstanceFields[6].Descriptor() + // paymentproviderinstance.DefaultLimits holds the default value on creation for the limits field. + paymentproviderinstance.DefaultLimits = paymentproviderinstanceDescLimits.Default.(string) + // paymentproviderinstanceDescRefundEnabled is the schema descriptor for refund_enabled field. + paymentproviderinstanceDescRefundEnabled := paymentproviderinstanceFields[7].Descriptor() + // paymentproviderinstance.DefaultRefundEnabled holds the default value on creation for the refund_enabled field. + paymentproviderinstance.DefaultRefundEnabled = paymentproviderinstanceDescRefundEnabled.Default.(bool) + // paymentproviderinstanceDescCreatedAt is the schema descriptor for created_at field. + paymentproviderinstanceDescCreatedAt := paymentproviderinstanceFields[8].Descriptor() + // paymentproviderinstance.DefaultCreatedAt holds the default value on creation for the created_at field. + paymentproviderinstance.DefaultCreatedAt = paymentproviderinstanceDescCreatedAt.Default.(func() time.Time) + // paymentproviderinstanceDescUpdatedAt is the schema descriptor for updated_at field. + paymentproviderinstanceDescUpdatedAt := paymentproviderinstanceFields[9].Descriptor() + // paymentproviderinstance.DefaultUpdatedAt holds the default value on creation for the updated_at field. + paymentproviderinstance.DefaultUpdatedAt = paymentproviderinstanceDescUpdatedAt.Default.(func() time.Time) + // paymentproviderinstance.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field. + paymentproviderinstance.UpdateDefaultUpdatedAt = paymentproviderinstanceDescUpdatedAt.UpdateDefault.(func() time.Time) promocodeFields := schema.PromoCode{}.Fields() _ = promocodeFields // promocodeDescCode is the schema descriptor for code field. @@ -751,6 +909,68 @@ func init() { setting.DefaultUpdatedAt = settingDescUpdatedAt.Default.(func() time.Time) // setting.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field. setting.UpdateDefaultUpdatedAt = settingDescUpdatedAt.UpdateDefault.(func() time.Time) + subscriptionplanFields := schema.SubscriptionPlan{}.Fields() + _ = subscriptionplanFields + // subscriptionplanDescName is the schema descriptor for name field. + subscriptionplanDescName := subscriptionplanFields[1].Descriptor() + // subscriptionplan.NameValidator is a validator for the "name" field. It is called by the builders before save. + subscriptionplan.NameValidator = func() func(string) error { + validators := subscriptionplanDescName.Validators + fns := [...]func(string) error{ + validators[0].(func(string) error), + validators[1].(func(string) error), + } + return func(name string) error { + for _, fn := range fns { + if err := fn(name); err != nil { + return err + } + } + return nil + } + }() + // subscriptionplanDescDescription is the schema descriptor for description field. + subscriptionplanDescDescription := subscriptionplanFields[2].Descriptor() + // subscriptionplan.DefaultDescription holds the default value on creation for the description field. + subscriptionplan.DefaultDescription = subscriptionplanDescDescription.Default.(string) + // subscriptionplanDescValidityDays is the schema descriptor for validity_days field. + subscriptionplanDescValidityDays := subscriptionplanFields[5].Descriptor() + // subscriptionplan.DefaultValidityDays holds the default value on creation for the validity_days field. + subscriptionplan.DefaultValidityDays = subscriptionplanDescValidityDays.Default.(int) + // subscriptionplanDescValidityUnit is the schema descriptor for validity_unit field. + subscriptionplanDescValidityUnit := subscriptionplanFields[6].Descriptor() + // subscriptionplan.DefaultValidityUnit holds the default value on creation for the validity_unit field. + subscriptionplan.DefaultValidityUnit = subscriptionplanDescValidityUnit.Default.(string) + // subscriptionplan.ValidityUnitValidator is a validator for the "validity_unit" field. It is called by the builders before save. + subscriptionplan.ValidityUnitValidator = subscriptionplanDescValidityUnit.Validators[0].(func(string) error) + // subscriptionplanDescFeatures is the schema descriptor for features field. + subscriptionplanDescFeatures := subscriptionplanFields[7].Descriptor() + // subscriptionplan.DefaultFeatures holds the default value on creation for the features field. + subscriptionplan.DefaultFeatures = subscriptionplanDescFeatures.Default.(string) + // subscriptionplanDescProductName is the schema descriptor for product_name field. + subscriptionplanDescProductName := subscriptionplanFields[8].Descriptor() + // subscriptionplan.DefaultProductName holds the default value on creation for the product_name field. + subscriptionplan.DefaultProductName = subscriptionplanDescProductName.Default.(string) + // subscriptionplan.ProductNameValidator is a validator for the "product_name" field. It is called by the builders before save. + subscriptionplan.ProductNameValidator = subscriptionplanDescProductName.Validators[0].(func(string) error) + // subscriptionplanDescForSale is the schema descriptor for for_sale field. + subscriptionplanDescForSale := subscriptionplanFields[9].Descriptor() + // subscriptionplan.DefaultForSale holds the default value on creation for the for_sale field. + subscriptionplan.DefaultForSale = subscriptionplanDescForSale.Default.(bool) + // subscriptionplanDescSortOrder is the schema descriptor for sort_order field. + subscriptionplanDescSortOrder := subscriptionplanFields[10].Descriptor() + // subscriptionplan.DefaultSortOrder holds the default value on creation for the sort_order field. + subscriptionplan.DefaultSortOrder = subscriptionplanDescSortOrder.Default.(int) + // subscriptionplanDescCreatedAt is the schema descriptor for created_at field. + subscriptionplanDescCreatedAt := subscriptionplanFields[11].Descriptor() + // subscriptionplan.DefaultCreatedAt holds the default value on creation for the created_at field. + subscriptionplan.DefaultCreatedAt = subscriptionplanDescCreatedAt.Default.(func() time.Time) + // subscriptionplanDescUpdatedAt is the schema descriptor for updated_at field. + subscriptionplanDescUpdatedAt := subscriptionplanFields[12].Descriptor() + // subscriptionplan.DefaultUpdatedAt holds the default value on creation for the updated_at field. + subscriptionplan.DefaultUpdatedAt = subscriptionplanDescUpdatedAt.Default.(func() time.Time) + // subscriptionplan.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field. + subscriptionplan.UpdateDefaultUpdatedAt = subscriptionplanDescUpdatedAt.UpdateDefault.(func() time.Time) tlsfingerprintprofileMixin := schema.TLSFingerprintProfile{}.Mixin() tlsfingerprintprofileMixinFields0 := tlsfingerprintprofileMixin[0].Fields() _ = tlsfingerprintprofileMixinFields0 diff --git a/backend/ent/schema/payment_audit_log.go b/backend/ent/schema/payment_audit_log.go new file mode 100644 index 0000000000..7f8a8c0442 --- /dev/null +++ b/backend/ent/schema/payment_audit_log.go @@ -0,0 +1,54 @@ +package schema + +import ( + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/entsql" + "entgo.io/ent/schema" + "entgo.io/ent/schema/field" + "entgo.io/ent/schema/index" +) + +// PaymentAuditLog holds the schema definition for the PaymentAuditLog entity. +// +// 删除策略:硬删除 +// PaymentAuditLog 使用硬删除而非软删除,原因如下: +// - 审计日志本身即为不可变记录,通常只追加不修改 +// - 如需清理历史日志,直接按时间范围批量删除即可 +// - 保持表结构简洁,提升插入和查询性能 +type PaymentAuditLog struct { + ent.Schema +} + +func (PaymentAuditLog) Annotations() []schema.Annotation { + return []schema.Annotation{ + entsql.Annotation{Table: "payment_audit_logs"}, + } +} + +func (PaymentAuditLog) Fields() []ent.Field { + return []ent.Field{ + field.String("order_id"). + MaxLen(64), + field.String("action"). + MaxLen(50), + field.String("detail"). + SchemaType(map[string]string{dialect.Postgres: "text"}). + Default(""), + field.String("operator"). + MaxLen(100). + Default("system"), + field.Time("created_at"). + Immutable(). + Default(time.Now). + SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), + } +} + +func (PaymentAuditLog) Indexes() []ent.Index { + return []ent.Index{ + index.Fields("order_id"), + } +} diff --git a/backend/ent/schema/payment_order.go b/backend/ent/schema/payment_order.go new file mode 100644 index 0000000000..c5fed1b421 --- /dev/null +++ b/backend/ent/schema/payment_order.go @@ -0,0 +1,186 @@ +package schema + +import ( + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/entsql" + "entgo.io/ent/schema" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" + "entgo.io/ent/schema/index" +) + +// PaymentOrder holds the schema definition for the PaymentOrder entity. +// +// 删除策略:硬删除 +// PaymentOrder 使用硬删除而非软删除,原因如下: +// - 订单通过 status 字段追踪完整生命周期,无需依赖软删除 +// - 订单审计通过 PaymentAuditLog 表记录,删除前可归档 +// - 减少查询复杂度,避免软删除过滤开销 +type PaymentOrder struct { + ent.Schema +} + +func (PaymentOrder) Annotations() []schema.Annotation { + return []schema.Annotation{ + entsql.Annotation{Table: "payment_orders"}, + } +} + +func (PaymentOrder) Fields() []ent.Field { + return []ent.Field{ + // 用户信息(冗余存储,避免关联查询) + field.Int64("user_id"), + field.String("user_email"). + MaxLen(255), + field.String("user_name"). + MaxLen(100), + field.String("user_notes"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "text"}), + + // 金额信息 + field.Float("amount"). + SchemaType(map[string]string{dialect.Postgres: "decimal(20,2)"}), + field.Float("pay_amount"). + SchemaType(map[string]string{dialect.Postgres: "decimal(20,2)"}), + field.Float("fee_rate"). + SchemaType(map[string]string{dialect.Postgres: "decimal(10,4)"}). + Default(0), + field.String("recharge_code"). + MaxLen(64), + + // 支付信息 + field.String("payment_type"). + MaxLen(30), + field.String("payment_trade_no"). + MaxLen(128), + field.String("pay_url"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "text"}), + field.String("qr_code"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "text"}), + field.String("qr_code_img"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "text"}), + + // 订单类型 & 订阅关联 + field.String("order_type"). + MaxLen(20). + Default("balance"), + field.Int64("plan_id"). + Optional(). + Nillable(), + field.Int64("subscription_group_id"). + Optional(). + Nillable(), + field.Int("subscription_days"). + Optional(). + Nillable(), + field.String("provider_instance_id"). + Optional(). + Nillable(). + MaxLen(64), + + // 状态 + field.String("status"). + MaxLen(30). + Default("PENDING"), + + // 退款信息 + field.Float("refund_amount"). + SchemaType(map[string]string{dialect.Postgres: "decimal(20,2)"}). + Default(0), + field.String("refund_reason"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "text"}), + field.Time("refund_at"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), + field.Bool("force_refund"). + Default(false), + field.Time("refund_requested_at"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), + field.String("refund_request_reason"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "text"}), + field.String("refund_requested_by"). + Optional(). + Nillable(). + MaxLen(20), + + // 时间节点 + field.Time("expires_at"). + SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), + field.Time("paid_at"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), + field.Time("completed_at"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), + field.Time("failed_at"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), + field.String("failed_reason"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "text"}), + + // 来源信息 + field.String("client_ip"). + MaxLen(50), + field.String("src_host"). + MaxLen(255), + field.String("src_url"). + Optional(). + Nillable(). + SchemaType(map[string]string{dialect.Postgres: "text"}), + + // 时间戳 + field.Time("created_at"). + Immutable(). + Default(time.Now). + SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), + field.Time("updated_at"). + Default(time.Now). + UpdateDefault(time.Now). + SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), + } +} + +func (PaymentOrder) Edges() []ent.Edge { + return []ent.Edge{ + edge.From("user", User.Type). + Ref("payment_orders"). + Field("user_id"). + Unique(). + Required(), + } +} + +func (PaymentOrder) Indexes() []ent.Index { + return []ent.Index{ + index.Fields("user_id"), + index.Fields("status"), + index.Fields("expires_at"), + index.Fields("created_at"), + index.Fields("paid_at"), + index.Fields("payment_type", "paid_at"), + index.Fields("order_type"), + } +} diff --git a/backend/ent/schema/payment_provider_instance.go b/backend/ent/schema/payment_provider_instance.go new file mode 100644 index 0000000000..395e0f83f4 --- /dev/null +++ b/backend/ent/schema/payment_provider_instance.go @@ -0,0 +1,69 @@ +package schema + +import ( + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/entsql" + "entgo.io/ent/schema" + "entgo.io/ent/schema/field" + "entgo.io/ent/schema/index" +) + +// PaymentProviderInstance holds the schema definition for the PaymentProviderInstance entity. +// +// 删除策略:硬删除 +// PaymentProviderInstance 使用硬删除而非软删除,原因如下: +// - 服务商实例为管理员配置的支付通道,删除即表示废弃 +// - 通过 enabled 字段控制是否启用,删除仅用于彻底移除 +// - config 字段存储加密后的密钥信息,删除时应彻底清除 +type PaymentProviderInstance struct { + ent.Schema +} + +func (PaymentProviderInstance) Annotations() []schema.Annotation { + return []schema.Annotation{ + entsql.Annotation{Table: "payment_provider_instances"}, + } +} + +func (PaymentProviderInstance) Fields() []ent.Field { + return []ent.Field{ + field.String("provider_key"). + MaxLen(30). + NotEmpty(), + field.String("name"). + MaxLen(100). + Default(""), + field.String("config"). + SchemaType(map[string]string{dialect.Postgres: "text"}), + field.String("supported_types"). + MaxLen(200). + Default(""), + field.Bool("enabled"). + Default(true), + field.Int("sort_order"). + Default(0), + field.String("limits"). + SchemaType(map[string]string{dialect.Postgres: "text"}). + Default(""), + field.Bool("refund_enabled"). + Default(false), + field.Time("created_at"). + Immutable(). + Default(time.Now). + SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), + field.Time("updated_at"). + Default(time.Now). + UpdateDefault(time.Now). + SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), + } +} + +func (PaymentProviderInstance) Indexes() []ent.Index { + return []ent.Index{ + index.Fields("provider_key"), + index.Fields("enabled"), + } +} diff --git a/backend/ent/schema/subscription_plan.go b/backend/ent/schema/subscription_plan.go new file mode 100644 index 0000000000..3e30490bb2 --- /dev/null +++ b/backend/ent/schema/subscription_plan.go @@ -0,0 +1,77 @@ +package schema + +import ( + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/entsql" + "entgo.io/ent/schema" + "entgo.io/ent/schema/field" + "entgo.io/ent/schema/index" +) + +// SubscriptionPlan holds the schema definition for the SubscriptionPlan entity. +// +// 删除策略:硬删除 +// SubscriptionPlan 使用硬删除而非软删除,原因如下: +// - 套餐为管理员维护的商品配置,删除即表示下架移除 +// - 通过 for_sale 字段控制是否在售,删除仅用于彻底移除 +// - 已购买的订阅记录保存在 UserSubscription 中,不受套餐删除影响 +type SubscriptionPlan struct { + ent.Schema +} + +func (SubscriptionPlan) Annotations() []schema.Annotation { + return []schema.Annotation{ + entsql.Annotation{Table: "subscription_plans"}, + } +} + +func (SubscriptionPlan) Fields() []ent.Field { + return []ent.Field{ + field.Int64("group_id"), + field.String("name"). + MaxLen(100). + NotEmpty(), + field.String("description"). + SchemaType(map[string]string{dialect.Postgres: "text"}). + Default(""), + field.Float("price"). + SchemaType(map[string]string{dialect.Postgres: "decimal(20,2)"}), + field.Float("original_price"). + SchemaType(map[string]string{dialect.Postgres: "decimal(20,2)"}). + Optional(). + Nillable(), + field.Int("validity_days"). + Default(30), + field.String("validity_unit"). + MaxLen(10). + Default("day"), + field.String("features"). + SchemaType(map[string]string{dialect.Postgres: "text"}). + Default(""), + field.String("product_name"). + MaxLen(100). + Default(""), + field.Bool("for_sale"). + Default(true), + field.Int("sort_order"). + Default(0), + field.Time("created_at"). + Immutable(). + Default(time.Now). + SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), + field.Time("updated_at"). + Default(time.Now). + UpdateDefault(time.Now). + SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), + } +} + +func (SubscriptionPlan) Indexes() []ent.Index { + return []ent.Index{ + index.Fields("group_id"), + index.Fields("for_sale"), + } +} diff --git a/backend/ent/schema/user.go b/backend/ent/schema/user.go index d443ef455c..af143d38ed 100644 --- a/backend/ent/schema/user.go +++ b/backend/ent/schema/user.go @@ -87,6 +87,7 @@ func (User) Edges() []ent.Edge { edge.To("usage_logs", UsageLog.Type), edge.To("attribute_values", UserAttributeValue.Type), edge.To("promo_code_usages", PromoCodeUsage.Type), + edge.To("payment_orders", PaymentOrder.Type), } } diff --git a/backend/ent/subscriptionplan.go b/backend/ent/subscriptionplan.go new file mode 100644 index 0000000000..fa4d7ae3b5 --- /dev/null +++ b/backend/ent/subscriptionplan.go @@ -0,0 +1,245 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "github.com/Wei-Shaw/sub2api/ent/subscriptionplan" +) + +// SubscriptionPlan is the model entity for the SubscriptionPlan schema. +type SubscriptionPlan struct { + config `json:"-"` + // ID of the ent. + ID int64 `json:"id,omitempty"` + // GroupID holds the value of the "group_id" field. + GroupID int64 `json:"group_id,omitempty"` + // Name holds the value of the "name" field. + Name string `json:"name,omitempty"` + // Description holds the value of the "description" field. + Description string `json:"description,omitempty"` + // Price holds the value of the "price" field. + Price float64 `json:"price,omitempty"` + // OriginalPrice holds the value of the "original_price" field. + OriginalPrice *float64 `json:"original_price,omitempty"` + // ValidityDays holds the value of the "validity_days" field. + ValidityDays int `json:"validity_days,omitempty"` + // ValidityUnit holds the value of the "validity_unit" field. + ValidityUnit string `json:"validity_unit,omitempty"` + // Features holds the value of the "features" field. + Features string `json:"features,omitempty"` + // ProductName holds the value of the "product_name" field. + ProductName string `json:"product_name,omitempty"` + // ForSale holds the value of the "for_sale" field. + ForSale bool `json:"for_sale,omitempty"` + // SortOrder holds the value of the "sort_order" field. + SortOrder int `json:"sort_order,omitempty"` + // CreatedAt holds the value of the "created_at" field. + CreatedAt time.Time `json:"created_at,omitempty"` + // UpdatedAt holds the value of the "updated_at" field. + UpdatedAt time.Time `json:"updated_at,omitempty"` + selectValues sql.SelectValues +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*SubscriptionPlan) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case subscriptionplan.FieldForSale: + values[i] = new(sql.NullBool) + case subscriptionplan.FieldPrice, subscriptionplan.FieldOriginalPrice: + values[i] = new(sql.NullFloat64) + case subscriptionplan.FieldID, subscriptionplan.FieldGroupID, subscriptionplan.FieldValidityDays, subscriptionplan.FieldSortOrder: + values[i] = new(sql.NullInt64) + case subscriptionplan.FieldName, subscriptionplan.FieldDescription, subscriptionplan.FieldValidityUnit, subscriptionplan.FieldFeatures, subscriptionplan.FieldProductName: + values[i] = new(sql.NullString) + case subscriptionplan.FieldCreatedAt, subscriptionplan.FieldUpdatedAt: + values[i] = new(sql.NullTime) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the SubscriptionPlan fields. +func (_m *SubscriptionPlan) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case subscriptionplan.FieldID: + value, ok := values[i].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + _m.ID = int64(value.Int64) + case subscriptionplan.FieldGroupID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field group_id", values[i]) + } else if value.Valid { + _m.GroupID = value.Int64 + } + case subscriptionplan.FieldName: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field name", values[i]) + } else if value.Valid { + _m.Name = value.String + } + case subscriptionplan.FieldDescription: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field description", values[i]) + } else if value.Valid { + _m.Description = value.String + } + case subscriptionplan.FieldPrice: + if value, ok := values[i].(*sql.NullFloat64); !ok { + return fmt.Errorf("unexpected type %T for field price", values[i]) + } else if value.Valid { + _m.Price = value.Float64 + } + case subscriptionplan.FieldOriginalPrice: + if value, ok := values[i].(*sql.NullFloat64); !ok { + return fmt.Errorf("unexpected type %T for field original_price", values[i]) + } else if value.Valid { + _m.OriginalPrice = new(float64) + *_m.OriginalPrice = value.Float64 + } + case subscriptionplan.FieldValidityDays: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field validity_days", values[i]) + } else if value.Valid { + _m.ValidityDays = int(value.Int64) + } + case subscriptionplan.FieldValidityUnit: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field validity_unit", values[i]) + } else if value.Valid { + _m.ValidityUnit = value.String + } + case subscriptionplan.FieldFeatures: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field features", values[i]) + } else if value.Valid { + _m.Features = value.String + } + case subscriptionplan.FieldProductName: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field product_name", values[i]) + } else if value.Valid { + _m.ProductName = value.String + } + case subscriptionplan.FieldForSale: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field for_sale", values[i]) + } else if value.Valid { + _m.ForSale = value.Bool + } + case subscriptionplan.FieldSortOrder: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field sort_order", values[i]) + } else if value.Valid { + _m.SortOrder = int(value.Int64) + } + case subscriptionplan.FieldCreatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field created_at", values[i]) + } else if value.Valid { + _m.CreatedAt = value.Time + } + case subscriptionplan.FieldUpdatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field updated_at", values[i]) + } else if value.Valid { + _m.UpdatedAt = value.Time + } + default: + _m.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the SubscriptionPlan. +// This includes values selected through modifiers, order, etc. +func (_m *SubscriptionPlan) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + +// Update returns a builder for updating this SubscriptionPlan. +// Note that you need to call SubscriptionPlan.Unwrap() before calling this method if this SubscriptionPlan +// was returned from a transaction, and the transaction was committed or rolled back. +func (_m *SubscriptionPlan) Update() *SubscriptionPlanUpdateOne { + return NewSubscriptionPlanClient(_m.config).UpdateOne(_m) +} + +// Unwrap unwraps the SubscriptionPlan entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (_m *SubscriptionPlan) Unwrap() *SubscriptionPlan { + _tx, ok := _m.config.driver.(*txDriver) + if !ok { + panic("ent: SubscriptionPlan is not a transactional entity") + } + _m.config.driver = _tx.drv + return _m +} + +// String implements the fmt.Stringer. +func (_m *SubscriptionPlan) String() string { + var builder strings.Builder + builder.WriteString("SubscriptionPlan(") + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) + builder.WriteString("group_id=") + builder.WriteString(fmt.Sprintf("%v", _m.GroupID)) + builder.WriteString(", ") + builder.WriteString("name=") + builder.WriteString(_m.Name) + builder.WriteString(", ") + builder.WriteString("description=") + builder.WriteString(_m.Description) + builder.WriteString(", ") + builder.WriteString("price=") + builder.WriteString(fmt.Sprintf("%v", _m.Price)) + builder.WriteString(", ") + if v := _m.OriginalPrice; v != nil { + builder.WriteString("original_price=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") + builder.WriteString("validity_days=") + builder.WriteString(fmt.Sprintf("%v", _m.ValidityDays)) + builder.WriteString(", ") + builder.WriteString("validity_unit=") + builder.WriteString(_m.ValidityUnit) + builder.WriteString(", ") + builder.WriteString("features=") + builder.WriteString(_m.Features) + builder.WriteString(", ") + builder.WriteString("product_name=") + builder.WriteString(_m.ProductName) + builder.WriteString(", ") + builder.WriteString("for_sale=") + builder.WriteString(fmt.Sprintf("%v", _m.ForSale)) + builder.WriteString(", ") + builder.WriteString("sort_order=") + builder.WriteString(fmt.Sprintf("%v", _m.SortOrder)) + builder.WriteString(", ") + builder.WriteString("created_at=") + builder.WriteString(_m.CreatedAt.Format(time.ANSIC)) + builder.WriteString(", ") + builder.WriteString("updated_at=") + builder.WriteString(_m.UpdatedAt.Format(time.ANSIC)) + builder.WriteByte(')') + return builder.String() +} + +// SubscriptionPlans is a parsable slice of SubscriptionPlan. +type SubscriptionPlans []*SubscriptionPlan diff --git a/backend/ent/subscriptionplan/subscriptionplan.go b/backend/ent/subscriptionplan/subscriptionplan.go new file mode 100644 index 0000000000..fa125aa714 --- /dev/null +++ b/backend/ent/subscriptionplan/subscriptionplan.go @@ -0,0 +1,174 @@ +// Code generated by ent, DO NOT EDIT. + +package subscriptionplan + +import ( + "time" + + "entgo.io/ent/dialect/sql" +) + +const ( + // Label holds the string label denoting the subscriptionplan type in the database. + Label = "subscription_plan" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldGroupID holds the string denoting the group_id field in the database. + FieldGroupID = "group_id" + // FieldName holds the string denoting the name field in the database. + FieldName = "name" + // FieldDescription holds the string denoting the description field in the database. + FieldDescription = "description" + // FieldPrice holds the string denoting the price field in the database. + FieldPrice = "price" + // FieldOriginalPrice holds the string denoting the original_price field in the database. + FieldOriginalPrice = "original_price" + // FieldValidityDays holds the string denoting the validity_days field in the database. + FieldValidityDays = "validity_days" + // FieldValidityUnit holds the string denoting the validity_unit field in the database. + FieldValidityUnit = "validity_unit" + // FieldFeatures holds the string denoting the features field in the database. + FieldFeatures = "features" + // FieldProductName holds the string denoting the product_name field in the database. + FieldProductName = "product_name" + // FieldForSale holds the string denoting the for_sale field in the database. + FieldForSale = "for_sale" + // FieldSortOrder holds the string denoting the sort_order field in the database. + FieldSortOrder = "sort_order" + // FieldCreatedAt holds the string denoting the created_at field in the database. + FieldCreatedAt = "created_at" + // FieldUpdatedAt holds the string denoting the updated_at field in the database. + FieldUpdatedAt = "updated_at" + // Table holds the table name of the subscriptionplan in the database. + Table = "subscription_plans" +) + +// Columns holds all SQL columns for subscriptionplan fields. +var Columns = []string{ + FieldID, + FieldGroupID, + FieldName, + FieldDescription, + FieldPrice, + FieldOriginalPrice, + FieldValidityDays, + FieldValidityUnit, + FieldFeatures, + FieldProductName, + FieldForSale, + FieldSortOrder, + FieldCreatedAt, + FieldUpdatedAt, +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + return false +} + +var ( + // NameValidator is a validator for the "name" field. It is called by the builders before save. + NameValidator func(string) error + // DefaultDescription holds the default value on creation for the "description" field. + DefaultDescription string + // DefaultValidityDays holds the default value on creation for the "validity_days" field. + DefaultValidityDays int + // DefaultValidityUnit holds the default value on creation for the "validity_unit" field. + DefaultValidityUnit string + // ValidityUnitValidator is a validator for the "validity_unit" field. It is called by the builders before save. + ValidityUnitValidator func(string) error + // DefaultFeatures holds the default value on creation for the "features" field. + DefaultFeatures string + // DefaultProductName holds the default value on creation for the "product_name" field. + DefaultProductName string + // ProductNameValidator is a validator for the "product_name" field. It is called by the builders before save. + ProductNameValidator func(string) error + // DefaultForSale holds the default value on creation for the "for_sale" field. + DefaultForSale bool + // DefaultSortOrder holds the default value on creation for the "sort_order" field. + DefaultSortOrder int + // DefaultCreatedAt holds the default value on creation for the "created_at" field. + DefaultCreatedAt func() time.Time + // DefaultUpdatedAt holds the default value on creation for the "updated_at" field. + DefaultUpdatedAt func() time.Time + // UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field. + UpdateDefaultUpdatedAt func() time.Time +) + +// OrderOption defines the ordering options for the SubscriptionPlan queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByGroupID orders the results by the group_id field. +func ByGroupID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldGroupID, opts...).ToFunc() +} + +// ByName orders the results by the name field. +func ByName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldName, opts...).ToFunc() +} + +// ByDescription orders the results by the description field. +func ByDescription(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldDescription, opts...).ToFunc() +} + +// ByPrice orders the results by the price field. +func ByPrice(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldPrice, opts...).ToFunc() +} + +// ByOriginalPrice orders the results by the original_price field. +func ByOriginalPrice(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldOriginalPrice, opts...).ToFunc() +} + +// ByValidityDays orders the results by the validity_days field. +func ByValidityDays(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldValidityDays, opts...).ToFunc() +} + +// ByValidityUnit orders the results by the validity_unit field. +func ByValidityUnit(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldValidityUnit, opts...).ToFunc() +} + +// ByFeatures orders the results by the features field. +func ByFeatures(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldFeatures, opts...).ToFunc() +} + +// ByProductName orders the results by the product_name field. +func ByProductName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldProductName, opts...).ToFunc() +} + +// ByForSale orders the results by the for_sale field. +func ByForSale(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldForSale, opts...).ToFunc() +} + +// BySortOrder orders the results by the sort_order field. +func BySortOrder(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldSortOrder, opts...).ToFunc() +} + +// ByCreatedAt orders the results by the created_at field. +func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() +} + +// ByUpdatedAt orders the results by the updated_at field. +func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc() +} diff --git a/backend/ent/subscriptionplan/where.go b/backend/ent/subscriptionplan/where.go new file mode 100644 index 0000000000..319cfdb509 --- /dev/null +++ b/backend/ent/subscriptionplan/where.go @@ -0,0 +1,760 @@ +// Code generated by ent, DO NOT EDIT. + +package subscriptionplan + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "github.com/Wei-Shaw/sub2api/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLTE(FieldID, id)) +} + +// GroupID applies equality check predicate on the "group_id" field. It's identical to GroupIDEQ. +func GroupID(v int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldGroupID, v)) +} + +// Name applies equality check predicate on the "name" field. It's identical to NameEQ. +func Name(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldName, v)) +} + +// Description applies equality check predicate on the "description" field. It's identical to DescriptionEQ. +func Description(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldDescription, v)) +} + +// Price applies equality check predicate on the "price" field. It's identical to PriceEQ. +func Price(v float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldPrice, v)) +} + +// OriginalPrice applies equality check predicate on the "original_price" field. It's identical to OriginalPriceEQ. +func OriginalPrice(v float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldOriginalPrice, v)) +} + +// ValidityDays applies equality check predicate on the "validity_days" field. It's identical to ValidityDaysEQ. +func ValidityDays(v int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldValidityDays, v)) +} + +// ValidityUnit applies equality check predicate on the "validity_unit" field. It's identical to ValidityUnitEQ. +func ValidityUnit(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldValidityUnit, v)) +} + +// Features applies equality check predicate on the "features" field. It's identical to FeaturesEQ. +func Features(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldFeatures, v)) +} + +// ProductName applies equality check predicate on the "product_name" field. It's identical to ProductNameEQ. +func ProductName(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldProductName, v)) +} + +// ForSale applies equality check predicate on the "for_sale" field. It's identical to ForSaleEQ. +func ForSale(v bool) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldForSale, v)) +} + +// SortOrder applies equality check predicate on the "sort_order" field. It's identical to SortOrderEQ. +func SortOrder(v int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldSortOrder, v)) +} + +// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. +func CreatedAt(v time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldCreatedAt, v)) +} + +// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ. +func UpdatedAt(v time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// GroupIDEQ applies the EQ predicate on the "group_id" field. +func GroupIDEQ(v int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldGroupID, v)) +} + +// GroupIDNEQ applies the NEQ predicate on the "group_id" field. +func GroupIDNEQ(v int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNEQ(FieldGroupID, v)) +} + +// GroupIDIn applies the In predicate on the "group_id" field. +func GroupIDIn(vs ...int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldIn(FieldGroupID, vs...)) +} + +// GroupIDNotIn applies the NotIn predicate on the "group_id" field. +func GroupIDNotIn(vs ...int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNotIn(FieldGroupID, vs...)) +} + +// GroupIDGT applies the GT predicate on the "group_id" field. +func GroupIDGT(v int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGT(FieldGroupID, v)) +} + +// GroupIDGTE applies the GTE predicate on the "group_id" field. +func GroupIDGTE(v int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGTE(FieldGroupID, v)) +} + +// GroupIDLT applies the LT predicate on the "group_id" field. +func GroupIDLT(v int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLT(FieldGroupID, v)) +} + +// GroupIDLTE applies the LTE predicate on the "group_id" field. +func GroupIDLTE(v int64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLTE(FieldGroupID, v)) +} + +// NameEQ applies the EQ predicate on the "name" field. +func NameEQ(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldName, v)) +} + +// NameNEQ applies the NEQ predicate on the "name" field. +func NameNEQ(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNEQ(FieldName, v)) +} + +// NameIn applies the In predicate on the "name" field. +func NameIn(vs ...string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldIn(FieldName, vs...)) +} + +// NameNotIn applies the NotIn predicate on the "name" field. +func NameNotIn(vs ...string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNotIn(FieldName, vs...)) +} + +// NameGT applies the GT predicate on the "name" field. +func NameGT(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGT(FieldName, v)) +} + +// NameGTE applies the GTE predicate on the "name" field. +func NameGTE(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGTE(FieldName, v)) +} + +// NameLT applies the LT predicate on the "name" field. +func NameLT(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLT(FieldName, v)) +} + +// NameLTE applies the LTE predicate on the "name" field. +func NameLTE(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLTE(FieldName, v)) +} + +// NameContains applies the Contains predicate on the "name" field. +func NameContains(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldContains(FieldName, v)) +} + +// NameHasPrefix applies the HasPrefix predicate on the "name" field. +func NameHasPrefix(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldHasPrefix(FieldName, v)) +} + +// NameHasSuffix applies the HasSuffix predicate on the "name" field. +func NameHasSuffix(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldHasSuffix(FieldName, v)) +} + +// NameEqualFold applies the EqualFold predicate on the "name" field. +func NameEqualFold(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEqualFold(FieldName, v)) +} + +// NameContainsFold applies the ContainsFold predicate on the "name" field. +func NameContainsFold(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldContainsFold(FieldName, v)) +} + +// DescriptionEQ applies the EQ predicate on the "description" field. +func DescriptionEQ(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldDescription, v)) +} + +// DescriptionNEQ applies the NEQ predicate on the "description" field. +func DescriptionNEQ(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNEQ(FieldDescription, v)) +} + +// DescriptionIn applies the In predicate on the "description" field. +func DescriptionIn(vs ...string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldIn(FieldDescription, vs...)) +} + +// DescriptionNotIn applies the NotIn predicate on the "description" field. +func DescriptionNotIn(vs ...string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNotIn(FieldDescription, vs...)) +} + +// DescriptionGT applies the GT predicate on the "description" field. +func DescriptionGT(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGT(FieldDescription, v)) +} + +// DescriptionGTE applies the GTE predicate on the "description" field. +func DescriptionGTE(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGTE(FieldDescription, v)) +} + +// DescriptionLT applies the LT predicate on the "description" field. +func DescriptionLT(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLT(FieldDescription, v)) +} + +// DescriptionLTE applies the LTE predicate on the "description" field. +func DescriptionLTE(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLTE(FieldDescription, v)) +} + +// DescriptionContains applies the Contains predicate on the "description" field. +func DescriptionContains(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldContains(FieldDescription, v)) +} + +// DescriptionHasPrefix applies the HasPrefix predicate on the "description" field. +func DescriptionHasPrefix(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldHasPrefix(FieldDescription, v)) +} + +// DescriptionHasSuffix applies the HasSuffix predicate on the "description" field. +func DescriptionHasSuffix(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldHasSuffix(FieldDescription, v)) +} + +// DescriptionEqualFold applies the EqualFold predicate on the "description" field. +func DescriptionEqualFold(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEqualFold(FieldDescription, v)) +} + +// DescriptionContainsFold applies the ContainsFold predicate on the "description" field. +func DescriptionContainsFold(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldContainsFold(FieldDescription, v)) +} + +// PriceEQ applies the EQ predicate on the "price" field. +func PriceEQ(v float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldPrice, v)) +} + +// PriceNEQ applies the NEQ predicate on the "price" field. +func PriceNEQ(v float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNEQ(FieldPrice, v)) +} + +// PriceIn applies the In predicate on the "price" field. +func PriceIn(vs ...float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldIn(FieldPrice, vs...)) +} + +// PriceNotIn applies the NotIn predicate on the "price" field. +func PriceNotIn(vs ...float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNotIn(FieldPrice, vs...)) +} + +// PriceGT applies the GT predicate on the "price" field. +func PriceGT(v float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGT(FieldPrice, v)) +} + +// PriceGTE applies the GTE predicate on the "price" field. +func PriceGTE(v float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGTE(FieldPrice, v)) +} + +// PriceLT applies the LT predicate on the "price" field. +func PriceLT(v float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLT(FieldPrice, v)) +} + +// PriceLTE applies the LTE predicate on the "price" field. +func PriceLTE(v float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLTE(FieldPrice, v)) +} + +// OriginalPriceEQ applies the EQ predicate on the "original_price" field. +func OriginalPriceEQ(v float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldOriginalPrice, v)) +} + +// OriginalPriceNEQ applies the NEQ predicate on the "original_price" field. +func OriginalPriceNEQ(v float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNEQ(FieldOriginalPrice, v)) +} + +// OriginalPriceIn applies the In predicate on the "original_price" field. +func OriginalPriceIn(vs ...float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldIn(FieldOriginalPrice, vs...)) +} + +// OriginalPriceNotIn applies the NotIn predicate on the "original_price" field. +func OriginalPriceNotIn(vs ...float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNotIn(FieldOriginalPrice, vs...)) +} + +// OriginalPriceGT applies the GT predicate on the "original_price" field. +func OriginalPriceGT(v float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGT(FieldOriginalPrice, v)) +} + +// OriginalPriceGTE applies the GTE predicate on the "original_price" field. +func OriginalPriceGTE(v float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGTE(FieldOriginalPrice, v)) +} + +// OriginalPriceLT applies the LT predicate on the "original_price" field. +func OriginalPriceLT(v float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLT(FieldOriginalPrice, v)) +} + +// OriginalPriceLTE applies the LTE predicate on the "original_price" field. +func OriginalPriceLTE(v float64) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLTE(FieldOriginalPrice, v)) +} + +// OriginalPriceIsNil applies the IsNil predicate on the "original_price" field. +func OriginalPriceIsNil() predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldIsNull(FieldOriginalPrice)) +} + +// OriginalPriceNotNil applies the NotNil predicate on the "original_price" field. +func OriginalPriceNotNil() predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNotNull(FieldOriginalPrice)) +} + +// ValidityDaysEQ applies the EQ predicate on the "validity_days" field. +func ValidityDaysEQ(v int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldValidityDays, v)) +} + +// ValidityDaysNEQ applies the NEQ predicate on the "validity_days" field. +func ValidityDaysNEQ(v int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNEQ(FieldValidityDays, v)) +} + +// ValidityDaysIn applies the In predicate on the "validity_days" field. +func ValidityDaysIn(vs ...int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldIn(FieldValidityDays, vs...)) +} + +// ValidityDaysNotIn applies the NotIn predicate on the "validity_days" field. +func ValidityDaysNotIn(vs ...int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNotIn(FieldValidityDays, vs...)) +} + +// ValidityDaysGT applies the GT predicate on the "validity_days" field. +func ValidityDaysGT(v int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGT(FieldValidityDays, v)) +} + +// ValidityDaysGTE applies the GTE predicate on the "validity_days" field. +func ValidityDaysGTE(v int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGTE(FieldValidityDays, v)) +} + +// ValidityDaysLT applies the LT predicate on the "validity_days" field. +func ValidityDaysLT(v int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLT(FieldValidityDays, v)) +} + +// ValidityDaysLTE applies the LTE predicate on the "validity_days" field. +func ValidityDaysLTE(v int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLTE(FieldValidityDays, v)) +} + +// ValidityUnitEQ applies the EQ predicate on the "validity_unit" field. +func ValidityUnitEQ(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldValidityUnit, v)) +} + +// ValidityUnitNEQ applies the NEQ predicate on the "validity_unit" field. +func ValidityUnitNEQ(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNEQ(FieldValidityUnit, v)) +} + +// ValidityUnitIn applies the In predicate on the "validity_unit" field. +func ValidityUnitIn(vs ...string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldIn(FieldValidityUnit, vs...)) +} + +// ValidityUnitNotIn applies the NotIn predicate on the "validity_unit" field. +func ValidityUnitNotIn(vs ...string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNotIn(FieldValidityUnit, vs...)) +} + +// ValidityUnitGT applies the GT predicate on the "validity_unit" field. +func ValidityUnitGT(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGT(FieldValidityUnit, v)) +} + +// ValidityUnitGTE applies the GTE predicate on the "validity_unit" field. +func ValidityUnitGTE(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGTE(FieldValidityUnit, v)) +} + +// ValidityUnitLT applies the LT predicate on the "validity_unit" field. +func ValidityUnitLT(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLT(FieldValidityUnit, v)) +} + +// ValidityUnitLTE applies the LTE predicate on the "validity_unit" field. +func ValidityUnitLTE(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLTE(FieldValidityUnit, v)) +} + +// ValidityUnitContains applies the Contains predicate on the "validity_unit" field. +func ValidityUnitContains(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldContains(FieldValidityUnit, v)) +} + +// ValidityUnitHasPrefix applies the HasPrefix predicate on the "validity_unit" field. +func ValidityUnitHasPrefix(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldHasPrefix(FieldValidityUnit, v)) +} + +// ValidityUnitHasSuffix applies the HasSuffix predicate on the "validity_unit" field. +func ValidityUnitHasSuffix(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldHasSuffix(FieldValidityUnit, v)) +} + +// ValidityUnitEqualFold applies the EqualFold predicate on the "validity_unit" field. +func ValidityUnitEqualFold(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEqualFold(FieldValidityUnit, v)) +} + +// ValidityUnitContainsFold applies the ContainsFold predicate on the "validity_unit" field. +func ValidityUnitContainsFold(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldContainsFold(FieldValidityUnit, v)) +} + +// FeaturesEQ applies the EQ predicate on the "features" field. +func FeaturesEQ(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldFeatures, v)) +} + +// FeaturesNEQ applies the NEQ predicate on the "features" field. +func FeaturesNEQ(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNEQ(FieldFeatures, v)) +} + +// FeaturesIn applies the In predicate on the "features" field. +func FeaturesIn(vs ...string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldIn(FieldFeatures, vs...)) +} + +// FeaturesNotIn applies the NotIn predicate on the "features" field. +func FeaturesNotIn(vs ...string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNotIn(FieldFeatures, vs...)) +} + +// FeaturesGT applies the GT predicate on the "features" field. +func FeaturesGT(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGT(FieldFeatures, v)) +} + +// FeaturesGTE applies the GTE predicate on the "features" field. +func FeaturesGTE(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGTE(FieldFeatures, v)) +} + +// FeaturesLT applies the LT predicate on the "features" field. +func FeaturesLT(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLT(FieldFeatures, v)) +} + +// FeaturesLTE applies the LTE predicate on the "features" field. +func FeaturesLTE(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLTE(FieldFeatures, v)) +} + +// FeaturesContains applies the Contains predicate on the "features" field. +func FeaturesContains(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldContains(FieldFeatures, v)) +} + +// FeaturesHasPrefix applies the HasPrefix predicate on the "features" field. +func FeaturesHasPrefix(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldHasPrefix(FieldFeatures, v)) +} + +// FeaturesHasSuffix applies the HasSuffix predicate on the "features" field. +func FeaturesHasSuffix(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldHasSuffix(FieldFeatures, v)) +} + +// FeaturesEqualFold applies the EqualFold predicate on the "features" field. +func FeaturesEqualFold(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEqualFold(FieldFeatures, v)) +} + +// FeaturesContainsFold applies the ContainsFold predicate on the "features" field. +func FeaturesContainsFold(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldContainsFold(FieldFeatures, v)) +} + +// ProductNameEQ applies the EQ predicate on the "product_name" field. +func ProductNameEQ(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldProductName, v)) +} + +// ProductNameNEQ applies the NEQ predicate on the "product_name" field. +func ProductNameNEQ(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNEQ(FieldProductName, v)) +} + +// ProductNameIn applies the In predicate on the "product_name" field. +func ProductNameIn(vs ...string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldIn(FieldProductName, vs...)) +} + +// ProductNameNotIn applies the NotIn predicate on the "product_name" field. +func ProductNameNotIn(vs ...string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNotIn(FieldProductName, vs...)) +} + +// ProductNameGT applies the GT predicate on the "product_name" field. +func ProductNameGT(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGT(FieldProductName, v)) +} + +// ProductNameGTE applies the GTE predicate on the "product_name" field. +func ProductNameGTE(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGTE(FieldProductName, v)) +} + +// ProductNameLT applies the LT predicate on the "product_name" field. +func ProductNameLT(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLT(FieldProductName, v)) +} + +// ProductNameLTE applies the LTE predicate on the "product_name" field. +func ProductNameLTE(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLTE(FieldProductName, v)) +} + +// ProductNameContains applies the Contains predicate on the "product_name" field. +func ProductNameContains(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldContains(FieldProductName, v)) +} + +// ProductNameHasPrefix applies the HasPrefix predicate on the "product_name" field. +func ProductNameHasPrefix(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldHasPrefix(FieldProductName, v)) +} + +// ProductNameHasSuffix applies the HasSuffix predicate on the "product_name" field. +func ProductNameHasSuffix(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldHasSuffix(FieldProductName, v)) +} + +// ProductNameEqualFold applies the EqualFold predicate on the "product_name" field. +func ProductNameEqualFold(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEqualFold(FieldProductName, v)) +} + +// ProductNameContainsFold applies the ContainsFold predicate on the "product_name" field. +func ProductNameContainsFold(v string) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldContainsFold(FieldProductName, v)) +} + +// ForSaleEQ applies the EQ predicate on the "for_sale" field. +func ForSaleEQ(v bool) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldForSale, v)) +} + +// ForSaleNEQ applies the NEQ predicate on the "for_sale" field. +func ForSaleNEQ(v bool) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNEQ(FieldForSale, v)) +} + +// SortOrderEQ applies the EQ predicate on the "sort_order" field. +func SortOrderEQ(v int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldSortOrder, v)) +} + +// SortOrderNEQ applies the NEQ predicate on the "sort_order" field. +func SortOrderNEQ(v int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNEQ(FieldSortOrder, v)) +} + +// SortOrderIn applies the In predicate on the "sort_order" field. +func SortOrderIn(vs ...int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldIn(FieldSortOrder, vs...)) +} + +// SortOrderNotIn applies the NotIn predicate on the "sort_order" field. +func SortOrderNotIn(vs ...int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNotIn(FieldSortOrder, vs...)) +} + +// SortOrderGT applies the GT predicate on the "sort_order" field. +func SortOrderGT(v int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGT(FieldSortOrder, v)) +} + +// SortOrderGTE applies the GTE predicate on the "sort_order" field. +func SortOrderGTE(v int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGTE(FieldSortOrder, v)) +} + +// SortOrderLT applies the LT predicate on the "sort_order" field. +func SortOrderLT(v int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLT(FieldSortOrder, v)) +} + +// SortOrderLTE applies the LTE predicate on the "sort_order" field. +func SortOrderLTE(v int) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLTE(FieldSortOrder, v)) +} + +// CreatedAtEQ applies the EQ predicate on the "created_at" field. +func CreatedAtEQ(v time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldCreatedAt, v)) +} + +// CreatedAtNEQ applies the NEQ predicate on the "created_at" field. +func CreatedAtNEQ(v time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNEQ(FieldCreatedAt, v)) +} + +// CreatedAtIn applies the In predicate on the "created_at" field. +func CreatedAtIn(vs ...time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldIn(FieldCreatedAt, vs...)) +} + +// CreatedAtNotIn applies the NotIn predicate on the "created_at" field. +func CreatedAtNotIn(vs ...time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNotIn(FieldCreatedAt, vs...)) +} + +// CreatedAtGT applies the GT predicate on the "created_at" field. +func CreatedAtGT(v time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGT(FieldCreatedAt, v)) +} + +// CreatedAtGTE applies the GTE predicate on the "created_at" field. +func CreatedAtGTE(v time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGTE(FieldCreatedAt, v)) +} + +// CreatedAtLT applies the LT predicate on the "created_at" field. +func CreatedAtLT(v time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLT(FieldCreatedAt, v)) +} + +// CreatedAtLTE applies the LTE predicate on the "created_at" field. +func CreatedAtLTE(v time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLTE(FieldCreatedAt, v)) +} + +// UpdatedAtEQ applies the EQ predicate on the "updated_at" field. +func UpdatedAtEQ(v time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field. +func UpdatedAtNEQ(v time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtIn applies the In predicate on the "updated_at" field. +func UpdatedAtIn(vs ...time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field. +func UpdatedAtNotIn(vs ...time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldNotIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtGT applies the GT predicate on the "updated_at" field. +func UpdatedAtGT(v time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGT(FieldUpdatedAt, v)) +} + +// UpdatedAtGTE applies the GTE predicate on the "updated_at" field. +func UpdatedAtGTE(v time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldGTE(FieldUpdatedAt, v)) +} + +// UpdatedAtLT applies the LT predicate on the "updated_at" field. +func UpdatedAtLT(v time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLT(FieldUpdatedAt, v)) +} + +// UpdatedAtLTE applies the LTE predicate on the "updated_at" field. +func UpdatedAtLTE(v time.Time) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.FieldLTE(FieldUpdatedAt, v)) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.SubscriptionPlan) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.SubscriptionPlan) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.SubscriptionPlan) predicate.SubscriptionPlan { + return predicate.SubscriptionPlan(sql.NotPredicates(p)) +} diff --git a/backend/ent/subscriptionplan_create.go b/backend/ent/subscriptionplan_create.go new file mode 100644 index 0000000000..9109db3a01 --- /dev/null +++ b/backend/ent/subscriptionplan_create.go @@ -0,0 +1,1317 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/subscriptionplan" +) + +// SubscriptionPlanCreate is the builder for creating a SubscriptionPlan entity. +type SubscriptionPlanCreate struct { + config + mutation *SubscriptionPlanMutation + hooks []Hook + conflict []sql.ConflictOption +} + +// SetGroupID sets the "group_id" field. +func (_c *SubscriptionPlanCreate) SetGroupID(v int64) *SubscriptionPlanCreate { + _c.mutation.SetGroupID(v) + return _c +} + +// SetName sets the "name" field. +func (_c *SubscriptionPlanCreate) SetName(v string) *SubscriptionPlanCreate { + _c.mutation.SetName(v) + return _c +} + +// SetDescription sets the "description" field. +func (_c *SubscriptionPlanCreate) SetDescription(v string) *SubscriptionPlanCreate { + _c.mutation.SetDescription(v) + return _c +} + +// SetNillableDescription sets the "description" field if the given value is not nil. +func (_c *SubscriptionPlanCreate) SetNillableDescription(v *string) *SubscriptionPlanCreate { + if v != nil { + _c.SetDescription(*v) + } + return _c +} + +// SetPrice sets the "price" field. +func (_c *SubscriptionPlanCreate) SetPrice(v float64) *SubscriptionPlanCreate { + _c.mutation.SetPrice(v) + return _c +} + +// SetOriginalPrice sets the "original_price" field. +func (_c *SubscriptionPlanCreate) SetOriginalPrice(v float64) *SubscriptionPlanCreate { + _c.mutation.SetOriginalPrice(v) + return _c +} + +// SetNillableOriginalPrice sets the "original_price" field if the given value is not nil. +func (_c *SubscriptionPlanCreate) SetNillableOriginalPrice(v *float64) *SubscriptionPlanCreate { + if v != nil { + _c.SetOriginalPrice(*v) + } + return _c +} + +// SetValidityDays sets the "validity_days" field. +func (_c *SubscriptionPlanCreate) SetValidityDays(v int) *SubscriptionPlanCreate { + _c.mutation.SetValidityDays(v) + return _c +} + +// SetNillableValidityDays sets the "validity_days" field if the given value is not nil. +func (_c *SubscriptionPlanCreate) SetNillableValidityDays(v *int) *SubscriptionPlanCreate { + if v != nil { + _c.SetValidityDays(*v) + } + return _c +} + +// SetValidityUnit sets the "validity_unit" field. +func (_c *SubscriptionPlanCreate) SetValidityUnit(v string) *SubscriptionPlanCreate { + _c.mutation.SetValidityUnit(v) + return _c +} + +// SetNillableValidityUnit sets the "validity_unit" field if the given value is not nil. +func (_c *SubscriptionPlanCreate) SetNillableValidityUnit(v *string) *SubscriptionPlanCreate { + if v != nil { + _c.SetValidityUnit(*v) + } + return _c +} + +// SetFeatures sets the "features" field. +func (_c *SubscriptionPlanCreate) SetFeatures(v string) *SubscriptionPlanCreate { + _c.mutation.SetFeatures(v) + return _c +} + +// SetNillableFeatures sets the "features" field if the given value is not nil. +func (_c *SubscriptionPlanCreate) SetNillableFeatures(v *string) *SubscriptionPlanCreate { + if v != nil { + _c.SetFeatures(*v) + } + return _c +} + +// SetProductName sets the "product_name" field. +func (_c *SubscriptionPlanCreate) SetProductName(v string) *SubscriptionPlanCreate { + _c.mutation.SetProductName(v) + return _c +} + +// SetNillableProductName sets the "product_name" field if the given value is not nil. +func (_c *SubscriptionPlanCreate) SetNillableProductName(v *string) *SubscriptionPlanCreate { + if v != nil { + _c.SetProductName(*v) + } + return _c +} + +// SetForSale sets the "for_sale" field. +func (_c *SubscriptionPlanCreate) SetForSale(v bool) *SubscriptionPlanCreate { + _c.mutation.SetForSale(v) + return _c +} + +// SetNillableForSale sets the "for_sale" field if the given value is not nil. +func (_c *SubscriptionPlanCreate) SetNillableForSale(v *bool) *SubscriptionPlanCreate { + if v != nil { + _c.SetForSale(*v) + } + return _c +} + +// SetSortOrder sets the "sort_order" field. +func (_c *SubscriptionPlanCreate) SetSortOrder(v int) *SubscriptionPlanCreate { + _c.mutation.SetSortOrder(v) + return _c +} + +// SetNillableSortOrder sets the "sort_order" field if the given value is not nil. +func (_c *SubscriptionPlanCreate) SetNillableSortOrder(v *int) *SubscriptionPlanCreate { + if v != nil { + _c.SetSortOrder(*v) + } + return _c +} + +// SetCreatedAt sets the "created_at" field. +func (_c *SubscriptionPlanCreate) SetCreatedAt(v time.Time) *SubscriptionPlanCreate { + _c.mutation.SetCreatedAt(v) + return _c +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (_c *SubscriptionPlanCreate) SetNillableCreatedAt(v *time.Time) *SubscriptionPlanCreate { + if v != nil { + _c.SetCreatedAt(*v) + } + return _c +} + +// SetUpdatedAt sets the "updated_at" field. +func (_c *SubscriptionPlanCreate) SetUpdatedAt(v time.Time) *SubscriptionPlanCreate { + _c.mutation.SetUpdatedAt(v) + return _c +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (_c *SubscriptionPlanCreate) SetNillableUpdatedAt(v *time.Time) *SubscriptionPlanCreate { + if v != nil { + _c.SetUpdatedAt(*v) + } + return _c +} + +// Mutation returns the SubscriptionPlanMutation object of the builder. +func (_c *SubscriptionPlanCreate) Mutation() *SubscriptionPlanMutation { + return _c.mutation +} + +// Save creates the SubscriptionPlan in the database. +func (_c *SubscriptionPlanCreate) Save(ctx context.Context) (*SubscriptionPlan, error) { + _c.defaults() + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (_c *SubscriptionPlanCreate) SaveX(ctx context.Context) *SubscriptionPlan { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *SubscriptionPlanCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *SubscriptionPlanCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_c *SubscriptionPlanCreate) defaults() { + if _, ok := _c.mutation.Description(); !ok { + v := subscriptionplan.DefaultDescription + _c.mutation.SetDescription(v) + } + if _, ok := _c.mutation.ValidityDays(); !ok { + v := subscriptionplan.DefaultValidityDays + _c.mutation.SetValidityDays(v) + } + if _, ok := _c.mutation.ValidityUnit(); !ok { + v := subscriptionplan.DefaultValidityUnit + _c.mutation.SetValidityUnit(v) + } + if _, ok := _c.mutation.Features(); !ok { + v := subscriptionplan.DefaultFeatures + _c.mutation.SetFeatures(v) + } + if _, ok := _c.mutation.ProductName(); !ok { + v := subscriptionplan.DefaultProductName + _c.mutation.SetProductName(v) + } + if _, ok := _c.mutation.ForSale(); !ok { + v := subscriptionplan.DefaultForSale + _c.mutation.SetForSale(v) + } + if _, ok := _c.mutation.SortOrder(); !ok { + v := subscriptionplan.DefaultSortOrder + _c.mutation.SetSortOrder(v) + } + if _, ok := _c.mutation.CreatedAt(); !ok { + v := subscriptionplan.DefaultCreatedAt() + _c.mutation.SetCreatedAt(v) + } + if _, ok := _c.mutation.UpdatedAt(); !ok { + v := subscriptionplan.DefaultUpdatedAt() + _c.mutation.SetUpdatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_c *SubscriptionPlanCreate) check() error { + if _, ok := _c.mutation.GroupID(); !ok { + return &ValidationError{Name: "group_id", err: errors.New(`ent: missing required field "SubscriptionPlan.group_id"`)} + } + if _, ok := _c.mutation.Name(); !ok { + return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "SubscriptionPlan.name"`)} + } + if v, ok := _c.mutation.Name(); ok { + if err := subscriptionplan.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "SubscriptionPlan.name": %w`, err)} + } + } + if _, ok := _c.mutation.Description(); !ok { + return &ValidationError{Name: "description", err: errors.New(`ent: missing required field "SubscriptionPlan.description"`)} + } + if _, ok := _c.mutation.Price(); !ok { + return &ValidationError{Name: "price", err: errors.New(`ent: missing required field "SubscriptionPlan.price"`)} + } + if _, ok := _c.mutation.ValidityDays(); !ok { + return &ValidationError{Name: "validity_days", err: errors.New(`ent: missing required field "SubscriptionPlan.validity_days"`)} + } + if _, ok := _c.mutation.ValidityUnit(); !ok { + return &ValidationError{Name: "validity_unit", err: errors.New(`ent: missing required field "SubscriptionPlan.validity_unit"`)} + } + if v, ok := _c.mutation.ValidityUnit(); ok { + if err := subscriptionplan.ValidityUnitValidator(v); err != nil { + return &ValidationError{Name: "validity_unit", err: fmt.Errorf(`ent: validator failed for field "SubscriptionPlan.validity_unit": %w`, err)} + } + } + if _, ok := _c.mutation.Features(); !ok { + return &ValidationError{Name: "features", err: errors.New(`ent: missing required field "SubscriptionPlan.features"`)} + } + if _, ok := _c.mutation.ProductName(); !ok { + return &ValidationError{Name: "product_name", err: errors.New(`ent: missing required field "SubscriptionPlan.product_name"`)} + } + if v, ok := _c.mutation.ProductName(); ok { + if err := subscriptionplan.ProductNameValidator(v); err != nil { + return &ValidationError{Name: "product_name", err: fmt.Errorf(`ent: validator failed for field "SubscriptionPlan.product_name": %w`, err)} + } + } + if _, ok := _c.mutation.ForSale(); !ok { + return &ValidationError{Name: "for_sale", err: errors.New(`ent: missing required field "SubscriptionPlan.for_sale"`)} + } + if _, ok := _c.mutation.SortOrder(); !ok { + return &ValidationError{Name: "sort_order", err: errors.New(`ent: missing required field "SubscriptionPlan.sort_order"`)} + } + if _, ok := _c.mutation.CreatedAt(); !ok { + return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "SubscriptionPlan.created_at"`)} + } + if _, ok := _c.mutation.UpdatedAt(); !ok { + return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "SubscriptionPlan.updated_at"`)} + } + return nil +} + +func (_c *SubscriptionPlanCreate) sqlSave(ctx context.Context) (*SubscriptionPlan, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + id := _spec.ID.Value.(int64) + _node.ID = int64(id) + _c.mutation.id = &_node.ID + _c.mutation.done = true + return _node, nil +} + +func (_c *SubscriptionPlanCreate) createSpec() (*SubscriptionPlan, *sqlgraph.CreateSpec) { + var ( + _node = &SubscriptionPlan{config: _c.config} + _spec = sqlgraph.NewCreateSpec(subscriptionplan.Table, sqlgraph.NewFieldSpec(subscriptionplan.FieldID, field.TypeInt64)) + ) + _spec.OnConflict = _c.conflict + if value, ok := _c.mutation.GroupID(); ok { + _spec.SetField(subscriptionplan.FieldGroupID, field.TypeInt64, value) + _node.GroupID = value + } + if value, ok := _c.mutation.Name(); ok { + _spec.SetField(subscriptionplan.FieldName, field.TypeString, value) + _node.Name = value + } + if value, ok := _c.mutation.Description(); ok { + _spec.SetField(subscriptionplan.FieldDescription, field.TypeString, value) + _node.Description = value + } + if value, ok := _c.mutation.Price(); ok { + _spec.SetField(subscriptionplan.FieldPrice, field.TypeFloat64, value) + _node.Price = value + } + if value, ok := _c.mutation.OriginalPrice(); ok { + _spec.SetField(subscriptionplan.FieldOriginalPrice, field.TypeFloat64, value) + _node.OriginalPrice = &value + } + if value, ok := _c.mutation.ValidityDays(); ok { + _spec.SetField(subscriptionplan.FieldValidityDays, field.TypeInt, value) + _node.ValidityDays = value + } + if value, ok := _c.mutation.ValidityUnit(); ok { + _spec.SetField(subscriptionplan.FieldValidityUnit, field.TypeString, value) + _node.ValidityUnit = value + } + if value, ok := _c.mutation.Features(); ok { + _spec.SetField(subscriptionplan.FieldFeatures, field.TypeString, value) + _node.Features = value + } + if value, ok := _c.mutation.ProductName(); ok { + _spec.SetField(subscriptionplan.FieldProductName, field.TypeString, value) + _node.ProductName = value + } + if value, ok := _c.mutation.ForSale(); ok { + _spec.SetField(subscriptionplan.FieldForSale, field.TypeBool, value) + _node.ForSale = value + } + if value, ok := _c.mutation.SortOrder(); ok { + _spec.SetField(subscriptionplan.FieldSortOrder, field.TypeInt, value) + _node.SortOrder = value + } + if value, ok := _c.mutation.CreatedAt(); ok { + _spec.SetField(subscriptionplan.FieldCreatedAt, field.TypeTime, value) + _node.CreatedAt = value + } + if value, ok := _c.mutation.UpdatedAt(); ok { + _spec.SetField(subscriptionplan.FieldUpdatedAt, field.TypeTime, value) + _node.UpdatedAt = value + } + return _node, _spec +} + +// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause +// of the `INSERT` statement. For example: +// +// client.SubscriptionPlan.Create(). +// SetGroupID(v). +// OnConflict( +// // Update the row with the new values +// // the was proposed for insertion. +// sql.ResolveWithNewValues(), +// ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.SubscriptionPlanUpsert) { +// SetGroupID(v+v). +// }). +// Exec(ctx) +func (_c *SubscriptionPlanCreate) OnConflict(opts ...sql.ConflictOption) *SubscriptionPlanUpsertOne { + _c.conflict = opts + return &SubscriptionPlanUpsertOne{ + create: _c, + } +} + +// OnConflictColumns calls `OnConflict` and configures the columns +// as conflict target. Using this option is equivalent to using: +// +// client.SubscriptionPlan.Create(). +// OnConflict(sql.ConflictColumns(columns...)). +// Exec(ctx) +func (_c *SubscriptionPlanCreate) OnConflictColumns(columns ...string) *SubscriptionPlanUpsertOne { + _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) + return &SubscriptionPlanUpsertOne{ + create: _c, + } +} + +type ( + // SubscriptionPlanUpsertOne is the builder for "upsert"-ing + // one SubscriptionPlan node. + SubscriptionPlanUpsertOne struct { + create *SubscriptionPlanCreate + } + + // SubscriptionPlanUpsert is the "OnConflict" setter. + SubscriptionPlanUpsert struct { + *sql.UpdateSet + } +) + +// SetGroupID sets the "group_id" field. +func (u *SubscriptionPlanUpsert) SetGroupID(v int64) *SubscriptionPlanUpsert { + u.Set(subscriptionplan.FieldGroupID, v) + return u +} + +// UpdateGroupID sets the "group_id" field to the value that was provided on create. +func (u *SubscriptionPlanUpsert) UpdateGroupID() *SubscriptionPlanUpsert { + u.SetExcluded(subscriptionplan.FieldGroupID) + return u +} + +// AddGroupID adds v to the "group_id" field. +func (u *SubscriptionPlanUpsert) AddGroupID(v int64) *SubscriptionPlanUpsert { + u.Add(subscriptionplan.FieldGroupID, v) + return u +} + +// SetName sets the "name" field. +func (u *SubscriptionPlanUpsert) SetName(v string) *SubscriptionPlanUpsert { + u.Set(subscriptionplan.FieldName, v) + return u +} + +// UpdateName sets the "name" field to the value that was provided on create. +func (u *SubscriptionPlanUpsert) UpdateName() *SubscriptionPlanUpsert { + u.SetExcluded(subscriptionplan.FieldName) + return u +} + +// SetDescription sets the "description" field. +func (u *SubscriptionPlanUpsert) SetDescription(v string) *SubscriptionPlanUpsert { + u.Set(subscriptionplan.FieldDescription, v) + return u +} + +// UpdateDescription sets the "description" field to the value that was provided on create. +func (u *SubscriptionPlanUpsert) UpdateDescription() *SubscriptionPlanUpsert { + u.SetExcluded(subscriptionplan.FieldDescription) + return u +} + +// SetPrice sets the "price" field. +func (u *SubscriptionPlanUpsert) SetPrice(v float64) *SubscriptionPlanUpsert { + u.Set(subscriptionplan.FieldPrice, v) + return u +} + +// UpdatePrice sets the "price" field to the value that was provided on create. +func (u *SubscriptionPlanUpsert) UpdatePrice() *SubscriptionPlanUpsert { + u.SetExcluded(subscriptionplan.FieldPrice) + return u +} + +// AddPrice adds v to the "price" field. +func (u *SubscriptionPlanUpsert) AddPrice(v float64) *SubscriptionPlanUpsert { + u.Add(subscriptionplan.FieldPrice, v) + return u +} + +// SetOriginalPrice sets the "original_price" field. +func (u *SubscriptionPlanUpsert) SetOriginalPrice(v float64) *SubscriptionPlanUpsert { + u.Set(subscriptionplan.FieldOriginalPrice, v) + return u +} + +// UpdateOriginalPrice sets the "original_price" field to the value that was provided on create. +func (u *SubscriptionPlanUpsert) UpdateOriginalPrice() *SubscriptionPlanUpsert { + u.SetExcluded(subscriptionplan.FieldOriginalPrice) + return u +} + +// AddOriginalPrice adds v to the "original_price" field. +func (u *SubscriptionPlanUpsert) AddOriginalPrice(v float64) *SubscriptionPlanUpsert { + u.Add(subscriptionplan.FieldOriginalPrice, v) + return u +} + +// ClearOriginalPrice clears the value of the "original_price" field. +func (u *SubscriptionPlanUpsert) ClearOriginalPrice() *SubscriptionPlanUpsert { + u.SetNull(subscriptionplan.FieldOriginalPrice) + return u +} + +// SetValidityDays sets the "validity_days" field. +func (u *SubscriptionPlanUpsert) SetValidityDays(v int) *SubscriptionPlanUpsert { + u.Set(subscriptionplan.FieldValidityDays, v) + return u +} + +// UpdateValidityDays sets the "validity_days" field to the value that was provided on create. +func (u *SubscriptionPlanUpsert) UpdateValidityDays() *SubscriptionPlanUpsert { + u.SetExcluded(subscriptionplan.FieldValidityDays) + return u +} + +// AddValidityDays adds v to the "validity_days" field. +func (u *SubscriptionPlanUpsert) AddValidityDays(v int) *SubscriptionPlanUpsert { + u.Add(subscriptionplan.FieldValidityDays, v) + return u +} + +// SetValidityUnit sets the "validity_unit" field. +func (u *SubscriptionPlanUpsert) SetValidityUnit(v string) *SubscriptionPlanUpsert { + u.Set(subscriptionplan.FieldValidityUnit, v) + return u +} + +// UpdateValidityUnit sets the "validity_unit" field to the value that was provided on create. +func (u *SubscriptionPlanUpsert) UpdateValidityUnit() *SubscriptionPlanUpsert { + u.SetExcluded(subscriptionplan.FieldValidityUnit) + return u +} + +// SetFeatures sets the "features" field. +func (u *SubscriptionPlanUpsert) SetFeatures(v string) *SubscriptionPlanUpsert { + u.Set(subscriptionplan.FieldFeatures, v) + return u +} + +// UpdateFeatures sets the "features" field to the value that was provided on create. +func (u *SubscriptionPlanUpsert) UpdateFeatures() *SubscriptionPlanUpsert { + u.SetExcluded(subscriptionplan.FieldFeatures) + return u +} + +// SetProductName sets the "product_name" field. +func (u *SubscriptionPlanUpsert) SetProductName(v string) *SubscriptionPlanUpsert { + u.Set(subscriptionplan.FieldProductName, v) + return u +} + +// UpdateProductName sets the "product_name" field to the value that was provided on create. +func (u *SubscriptionPlanUpsert) UpdateProductName() *SubscriptionPlanUpsert { + u.SetExcluded(subscriptionplan.FieldProductName) + return u +} + +// SetForSale sets the "for_sale" field. +func (u *SubscriptionPlanUpsert) SetForSale(v bool) *SubscriptionPlanUpsert { + u.Set(subscriptionplan.FieldForSale, v) + return u +} + +// UpdateForSale sets the "for_sale" field to the value that was provided on create. +func (u *SubscriptionPlanUpsert) UpdateForSale() *SubscriptionPlanUpsert { + u.SetExcluded(subscriptionplan.FieldForSale) + return u +} + +// SetSortOrder sets the "sort_order" field. +func (u *SubscriptionPlanUpsert) SetSortOrder(v int) *SubscriptionPlanUpsert { + u.Set(subscriptionplan.FieldSortOrder, v) + return u +} + +// UpdateSortOrder sets the "sort_order" field to the value that was provided on create. +func (u *SubscriptionPlanUpsert) UpdateSortOrder() *SubscriptionPlanUpsert { + u.SetExcluded(subscriptionplan.FieldSortOrder) + return u +} + +// AddSortOrder adds v to the "sort_order" field. +func (u *SubscriptionPlanUpsert) AddSortOrder(v int) *SubscriptionPlanUpsert { + u.Add(subscriptionplan.FieldSortOrder, v) + return u +} + +// SetUpdatedAt sets the "updated_at" field. +func (u *SubscriptionPlanUpsert) SetUpdatedAt(v time.Time) *SubscriptionPlanUpsert { + u.Set(subscriptionplan.FieldUpdatedAt, v) + return u +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *SubscriptionPlanUpsert) UpdateUpdatedAt() *SubscriptionPlanUpsert { + u.SetExcluded(subscriptionplan.FieldUpdatedAt) + return u +} + +// UpdateNewValues updates the mutable fields using the new values that were set on create. +// Using this option is equivalent to using: +// +// client.SubscriptionPlan.Create(). +// OnConflict( +// sql.ResolveWithNewValues(), +// ). +// Exec(ctx) +func (u *SubscriptionPlanUpsertOne) UpdateNewValues() *SubscriptionPlanUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { + if _, exists := u.create.mutation.CreatedAt(); exists { + s.SetIgnore(subscriptionplan.FieldCreatedAt) + } + })) + return u +} + +// Ignore sets each column to itself in case of conflict. +// Using this option is equivalent to using: +// +// client.SubscriptionPlan.Create(). +// OnConflict(sql.ResolveWithIgnore()). +// Exec(ctx) +func (u *SubscriptionPlanUpsertOne) Ignore() *SubscriptionPlanUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) + return u +} + +// DoNothing configures the conflict_action to `DO NOTHING`. +// Supported only by SQLite and PostgreSQL. +func (u *SubscriptionPlanUpsertOne) DoNothing() *SubscriptionPlanUpsertOne { + u.create.conflict = append(u.create.conflict, sql.DoNothing()) + return u +} + +// Update allows overriding fields `UPDATE` values. See the SubscriptionPlanCreate.OnConflict +// documentation for more info. +func (u *SubscriptionPlanUpsertOne) Update(set func(*SubscriptionPlanUpsert)) *SubscriptionPlanUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { + set(&SubscriptionPlanUpsert{UpdateSet: update}) + })) + return u +} + +// SetGroupID sets the "group_id" field. +func (u *SubscriptionPlanUpsertOne) SetGroupID(v int64) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetGroupID(v) + }) +} + +// AddGroupID adds v to the "group_id" field. +func (u *SubscriptionPlanUpsertOne) AddGroupID(v int64) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.AddGroupID(v) + }) +} + +// UpdateGroupID sets the "group_id" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertOne) UpdateGroupID() *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateGroupID() + }) +} + +// SetName sets the "name" field. +func (u *SubscriptionPlanUpsertOne) SetName(v string) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetName(v) + }) +} + +// UpdateName sets the "name" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertOne) UpdateName() *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateName() + }) +} + +// SetDescription sets the "description" field. +func (u *SubscriptionPlanUpsertOne) SetDescription(v string) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetDescription(v) + }) +} + +// UpdateDescription sets the "description" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertOne) UpdateDescription() *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateDescription() + }) +} + +// SetPrice sets the "price" field. +func (u *SubscriptionPlanUpsertOne) SetPrice(v float64) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetPrice(v) + }) +} + +// AddPrice adds v to the "price" field. +func (u *SubscriptionPlanUpsertOne) AddPrice(v float64) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.AddPrice(v) + }) +} + +// UpdatePrice sets the "price" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertOne) UpdatePrice() *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdatePrice() + }) +} + +// SetOriginalPrice sets the "original_price" field. +func (u *SubscriptionPlanUpsertOne) SetOriginalPrice(v float64) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetOriginalPrice(v) + }) +} + +// AddOriginalPrice adds v to the "original_price" field. +func (u *SubscriptionPlanUpsertOne) AddOriginalPrice(v float64) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.AddOriginalPrice(v) + }) +} + +// UpdateOriginalPrice sets the "original_price" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertOne) UpdateOriginalPrice() *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateOriginalPrice() + }) +} + +// ClearOriginalPrice clears the value of the "original_price" field. +func (u *SubscriptionPlanUpsertOne) ClearOriginalPrice() *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.ClearOriginalPrice() + }) +} + +// SetValidityDays sets the "validity_days" field. +func (u *SubscriptionPlanUpsertOne) SetValidityDays(v int) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetValidityDays(v) + }) +} + +// AddValidityDays adds v to the "validity_days" field. +func (u *SubscriptionPlanUpsertOne) AddValidityDays(v int) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.AddValidityDays(v) + }) +} + +// UpdateValidityDays sets the "validity_days" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertOne) UpdateValidityDays() *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateValidityDays() + }) +} + +// SetValidityUnit sets the "validity_unit" field. +func (u *SubscriptionPlanUpsertOne) SetValidityUnit(v string) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetValidityUnit(v) + }) +} + +// UpdateValidityUnit sets the "validity_unit" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertOne) UpdateValidityUnit() *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateValidityUnit() + }) +} + +// SetFeatures sets the "features" field. +func (u *SubscriptionPlanUpsertOne) SetFeatures(v string) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetFeatures(v) + }) +} + +// UpdateFeatures sets the "features" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertOne) UpdateFeatures() *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateFeatures() + }) +} + +// SetProductName sets the "product_name" field. +func (u *SubscriptionPlanUpsertOne) SetProductName(v string) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetProductName(v) + }) +} + +// UpdateProductName sets the "product_name" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertOne) UpdateProductName() *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateProductName() + }) +} + +// SetForSale sets the "for_sale" field. +func (u *SubscriptionPlanUpsertOne) SetForSale(v bool) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetForSale(v) + }) +} + +// UpdateForSale sets the "for_sale" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertOne) UpdateForSale() *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateForSale() + }) +} + +// SetSortOrder sets the "sort_order" field. +func (u *SubscriptionPlanUpsertOne) SetSortOrder(v int) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetSortOrder(v) + }) +} + +// AddSortOrder adds v to the "sort_order" field. +func (u *SubscriptionPlanUpsertOne) AddSortOrder(v int) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.AddSortOrder(v) + }) +} + +// UpdateSortOrder sets the "sort_order" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertOne) UpdateSortOrder() *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateSortOrder() + }) +} + +// SetUpdatedAt sets the "updated_at" field. +func (u *SubscriptionPlanUpsertOne) SetUpdatedAt(v time.Time) *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetUpdatedAt(v) + }) +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertOne) UpdateUpdatedAt() *SubscriptionPlanUpsertOne { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateUpdatedAt() + }) +} + +// Exec executes the query. +func (u *SubscriptionPlanUpsertOne) Exec(ctx context.Context) error { + if len(u.create.conflict) == 0 { + return errors.New("ent: missing options for SubscriptionPlanCreate.OnConflict") + } + return u.create.Exec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (u *SubscriptionPlanUpsertOne) ExecX(ctx context.Context) { + if err := u.create.Exec(ctx); err != nil { + panic(err) + } +} + +// Exec executes the UPSERT query and returns the inserted/updated ID. +func (u *SubscriptionPlanUpsertOne) ID(ctx context.Context) (id int64, err error) { + node, err := u.create.Save(ctx) + if err != nil { + return id, err + } + return node.ID, nil +} + +// IDX is like ID, but panics if an error occurs. +func (u *SubscriptionPlanUpsertOne) IDX(ctx context.Context) int64 { + id, err := u.ID(ctx) + if err != nil { + panic(err) + } + return id +} + +// SubscriptionPlanCreateBulk is the builder for creating many SubscriptionPlan entities in bulk. +type SubscriptionPlanCreateBulk struct { + config + err error + builders []*SubscriptionPlanCreate + conflict []sql.ConflictOption +} + +// Save creates the SubscriptionPlan entities in the database. +func (_c *SubscriptionPlanCreateBulk) Save(ctx context.Context) ([]*SubscriptionPlan, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*SubscriptionPlan, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { + func(i int, root context.Context) { + builder := _c.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*SubscriptionPlanMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.OnConflict = _c.conflict + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + if specs[i].ID.Value != nil { + id := specs[i].ID.Value.(int64) + nodes[i].ID = int64(id) + } + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (_c *SubscriptionPlanCreateBulk) SaveX(ctx context.Context) []*SubscriptionPlan { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *SubscriptionPlanCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *SubscriptionPlanCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause +// of the `INSERT` statement. For example: +// +// client.SubscriptionPlan.CreateBulk(builders...). +// OnConflict( +// // Update the row with the new values +// // the was proposed for insertion. +// sql.ResolveWithNewValues(), +// ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.SubscriptionPlanUpsert) { +// SetGroupID(v+v). +// }). +// Exec(ctx) +func (_c *SubscriptionPlanCreateBulk) OnConflict(opts ...sql.ConflictOption) *SubscriptionPlanUpsertBulk { + _c.conflict = opts + return &SubscriptionPlanUpsertBulk{ + create: _c, + } +} + +// OnConflictColumns calls `OnConflict` and configures the columns +// as conflict target. Using this option is equivalent to using: +// +// client.SubscriptionPlan.Create(). +// OnConflict(sql.ConflictColumns(columns...)). +// Exec(ctx) +func (_c *SubscriptionPlanCreateBulk) OnConflictColumns(columns ...string) *SubscriptionPlanUpsertBulk { + _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) + return &SubscriptionPlanUpsertBulk{ + create: _c, + } +} + +// SubscriptionPlanUpsertBulk is the builder for "upsert"-ing +// a bulk of SubscriptionPlan nodes. +type SubscriptionPlanUpsertBulk struct { + create *SubscriptionPlanCreateBulk +} + +// UpdateNewValues updates the mutable fields using the new values that +// were set on create. Using this option is equivalent to using: +// +// client.SubscriptionPlan.Create(). +// OnConflict( +// sql.ResolveWithNewValues(), +// ). +// Exec(ctx) +func (u *SubscriptionPlanUpsertBulk) UpdateNewValues() *SubscriptionPlanUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { + for _, b := range u.create.builders { + if _, exists := b.mutation.CreatedAt(); exists { + s.SetIgnore(subscriptionplan.FieldCreatedAt) + } + } + })) + return u +} + +// Ignore sets each column to itself in case of conflict. +// Using this option is equivalent to using: +// +// client.SubscriptionPlan.Create(). +// OnConflict(sql.ResolveWithIgnore()). +// Exec(ctx) +func (u *SubscriptionPlanUpsertBulk) Ignore() *SubscriptionPlanUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) + return u +} + +// DoNothing configures the conflict_action to `DO NOTHING`. +// Supported only by SQLite and PostgreSQL. +func (u *SubscriptionPlanUpsertBulk) DoNothing() *SubscriptionPlanUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.DoNothing()) + return u +} + +// Update allows overriding fields `UPDATE` values. See the SubscriptionPlanCreateBulk.OnConflict +// documentation for more info. +func (u *SubscriptionPlanUpsertBulk) Update(set func(*SubscriptionPlanUpsert)) *SubscriptionPlanUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { + set(&SubscriptionPlanUpsert{UpdateSet: update}) + })) + return u +} + +// SetGroupID sets the "group_id" field. +func (u *SubscriptionPlanUpsertBulk) SetGroupID(v int64) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetGroupID(v) + }) +} + +// AddGroupID adds v to the "group_id" field. +func (u *SubscriptionPlanUpsertBulk) AddGroupID(v int64) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.AddGroupID(v) + }) +} + +// UpdateGroupID sets the "group_id" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertBulk) UpdateGroupID() *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateGroupID() + }) +} + +// SetName sets the "name" field. +func (u *SubscriptionPlanUpsertBulk) SetName(v string) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetName(v) + }) +} + +// UpdateName sets the "name" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertBulk) UpdateName() *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateName() + }) +} + +// SetDescription sets the "description" field. +func (u *SubscriptionPlanUpsertBulk) SetDescription(v string) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetDescription(v) + }) +} + +// UpdateDescription sets the "description" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertBulk) UpdateDescription() *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateDescription() + }) +} + +// SetPrice sets the "price" field. +func (u *SubscriptionPlanUpsertBulk) SetPrice(v float64) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetPrice(v) + }) +} + +// AddPrice adds v to the "price" field. +func (u *SubscriptionPlanUpsertBulk) AddPrice(v float64) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.AddPrice(v) + }) +} + +// UpdatePrice sets the "price" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertBulk) UpdatePrice() *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdatePrice() + }) +} + +// SetOriginalPrice sets the "original_price" field. +func (u *SubscriptionPlanUpsertBulk) SetOriginalPrice(v float64) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetOriginalPrice(v) + }) +} + +// AddOriginalPrice adds v to the "original_price" field. +func (u *SubscriptionPlanUpsertBulk) AddOriginalPrice(v float64) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.AddOriginalPrice(v) + }) +} + +// UpdateOriginalPrice sets the "original_price" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertBulk) UpdateOriginalPrice() *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateOriginalPrice() + }) +} + +// ClearOriginalPrice clears the value of the "original_price" field. +func (u *SubscriptionPlanUpsertBulk) ClearOriginalPrice() *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.ClearOriginalPrice() + }) +} + +// SetValidityDays sets the "validity_days" field. +func (u *SubscriptionPlanUpsertBulk) SetValidityDays(v int) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetValidityDays(v) + }) +} + +// AddValidityDays adds v to the "validity_days" field. +func (u *SubscriptionPlanUpsertBulk) AddValidityDays(v int) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.AddValidityDays(v) + }) +} + +// UpdateValidityDays sets the "validity_days" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertBulk) UpdateValidityDays() *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateValidityDays() + }) +} + +// SetValidityUnit sets the "validity_unit" field. +func (u *SubscriptionPlanUpsertBulk) SetValidityUnit(v string) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetValidityUnit(v) + }) +} + +// UpdateValidityUnit sets the "validity_unit" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertBulk) UpdateValidityUnit() *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateValidityUnit() + }) +} + +// SetFeatures sets the "features" field. +func (u *SubscriptionPlanUpsertBulk) SetFeatures(v string) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetFeatures(v) + }) +} + +// UpdateFeatures sets the "features" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertBulk) UpdateFeatures() *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateFeatures() + }) +} + +// SetProductName sets the "product_name" field. +func (u *SubscriptionPlanUpsertBulk) SetProductName(v string) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetProductName(v) + }) +} + +// UpdateProductName sets the "product_name" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertBulk) UpdateProductName() *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateProductName() + }) +} + +// SetForSale sets the "for_sale" field. +func (u *SubscriptionPlanUpsertBulk) SetForSale(v bool) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetForSale(v) + }) +} + +// UpdateForSale sets the "for_sale" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertBulk) UpdateForSale() *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateForSale() + }) +} + +// SetSortOrder sets the "sort_order" field. +func (u *SubscriptionPlanUpsertBulk) SetSortOrder(v int) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetSortOrder(v) + }) +} + +// AddSortOrder adds v to the "sort_order" field. +func (u *SubscriptionPlanUpsertBulk) AddSortOrder(v int) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.AddSortOrder(v) + }) +} + +// UpdateSortOrder sets the "sort_order" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertBulk) UpdateSortOrder() *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateSortOrder() + }) +} + +// SetUpdatedAt sets the "updated_at" field. +func (u *SubscriptionPlanUpsertBulk) SetUpdatedAt(v time.Time) *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.SetUpdatedAt(v) + }) +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *SubscriptionPlanUpsertBulk) UpdateUpdatedAt() *SubscriptionPlanUpsertBulk { + return u.Update(func(s *SubscriptionPlanUpsert) { + s.UpdateUpdatedAt() + }) +} + +// Exec executes the query. +func (u *SubscriptionPlanUpsertBulk) Exec(ctx context.Context) error { + if u.create.err != nil { + return u.create.err + } + for i, b := range u.create.builders { + if len(b.conflict) != 0 { + return fmt.Errorf("ent: OnConflict was set for builder %d. Set it on the SubscriptionPlanCreateBulk instead", i) + } + } + if len(u.create.conflict) == 0 { + return errors.New("ent: missing options for SubscriptionPlanCreateBulk.OnConflict") + } + return u.create.Exec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (u *SubscriptionPlanUpsertBulk) ExecX(ctx context.Context) { + if err := u.create.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/backend/ent/subscriptionplan_delete.go b/backend/ent/subscriptionplan_delete.go new file mode 100644 index 0000000000..90c71239e2 --- /dev/null +++ b/backend/ent/subscriptionplan_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/predicate" + "github.com/Wei-Shaw/sub2api/ent/subscriptionplan" +) + +// SubscriptionPlanDelete is the builder for deleting a SubscriptionPlan entity. +type SubscriptionPlanDelete struct { + config + hooks []Hook + mutation *SubscriptionPlanMutation +} + +// Where appends a list predicates to the SubscriptionPlanDelete builder. +func (_d *SubscriptionPlanDelete) Where(ps ...predicate.SubscriptionPlan) *SubscriptionPlanDelete { + _d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (_d *SubscriptionPlanDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *SubscriptionPlanDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (_d *SubscriptionPlanDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(subscriptionplan.Table, sqlgraph.NewFieldSpec(subscriptionplan.FieldID, field.TypeInt64)) + if ps := _d.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + _d.mutation.done = true + return affected, err +} + +// SubscriptionPlanDeleteOne is the builder for deleting a single SubscriptionPlan entity. +type SubscriptionPlanDeleteOne struct { + _d *SubscriptionPlanDelete +} + +// Where appends a list predicates to the SubscriptionPlanDelete builder. +func (_d *SubscriptionPlanDeleteOne) Where(ps ...predicate.SubscriptionPlan) *SubscriptionPlanDeleteOne { + _d._d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query. +func (_d *SubscriptionPlanDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{subscriptionplan.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *SubscriptionPlanDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/backend/ent/subscriptionplan_query.go b/backend/ent/subscriptionplan_query.go new file mode 100644 index 0000000000..6c301dcd29 --- /dev/null +++ b/backend/ent/subscriptionplan_query.go @@ -0,0 +1,564 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "math" + + "entgo.io/ent" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/predicate" + "github.com/Wei-Shaw/sub2api/ent/subscriptionplan" +) + +// SubscriptionPlanQuery is the builder for querying SubscriptionPlan entities. +type SubscriptionPlanQuery struct { + config + ctx *QueryContext + order []subscriptionplan.OrderOption + inters []Interceptor + predicates []predicate.SubscriptionPlan + modifiers []func(*sql.Selector) + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the SubscriptionPlanQuery builder. +func (_q *SubscriptionPlanQuery) Where(ps ...predicate.SubscriptionPlan) *SubscriptionPlanQuery { + _q.predicates = append(_q.predicates, ps...) + return _q +} + +// Limit the number of records to be returned by this query. +func (_q *SubscriptionPlanQuery) Limit(limit int) *SubscriptionPlanQuery { + _q.ctx.Limit = &limit + return _q +} + +// Offset to start from. +func (_q *SubscriptionPlanQuery) Offset(offset int) *SubscriptionPlanQuery { + _q.ctx.Offset = &offset + return _q +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (_q *SubscriptionPlanQuery) Unique(unique bool) *SubscriptionPlanQuery { + _q.ctx.Unique = &unique + return _q +} + +// Order specifies how the records should be ordered. +func (_q *SubscriptionPlanQuery) Order(o ...subscriptionplan.OrderOption) *SubscriptionPlanQuery { + _q.order = append(_q.order, o...) + return _q +} + +// First returns the first SubscriptionPlan entity from the query. +// Returns a *NotFoundError when no SubscriptionPlan was found. +func (_q *SubscriptionPlanQuery) First(ctx context.Context) (*SubscriptionPlan, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{subscriptionplan.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (_q *SubscriptionPlanQuery) FirstX(ctx context.Context) *SubscriptionPlan { + node, err := _q.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first SubscriptionPlan ID from the query. +// Returns a *NotFoundError when no SubscriptionPlan ID was found. +func (_q *SubscriptionPlanQuery) FirstID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{subscriptionplan.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (_q *SubscriptionPlanQuery) FirstIDX(ctx context.Context) int64 { + id, err := _q.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single SubscriptionPlan entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one SubscriptionPlan entity is found. +// Returns a *NotFoundError when no SubscriptionPlan entities are found. +func (_q *SubscriptionPlanQuery) Only(ctx context.Context) (*SubscriptionPlan, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{subscriptionplan.Label} + default: + return nil, &NotSingularError{subscriptionplan.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (_q *SubscriptionPlanQuery) OnlyX(ctx context.Context) *SubscriptionPlan { + node, err := _q.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only SubscriptionPlan ID in the query. +// Returns a *NotSingularError when more than one SubscriptionPlan ID is found. +// Returns a *NotFoundError when no entities are found. +func (_q *SubscriptionPlanQuery) OnlyID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{subscriptionplan.Label} + default: + err = &NotSingularError{subscriptionplan.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (_q *SubscriptionPlanQuery) OnlyIDX(ctx context.Context) int64 { + id, err := _q.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of SubscriptionPlans. +func (_q *SubscriptionPlanQuery) All(ctx context.Context) ([]*SubscriptionPlan, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*SubscriptionPlan, *SubscriptionPlanQuery]() + return withInterceptors[[]*SubscriptionPlan](ctx, _q, qr, _q.inters) +} + +// AllX is like All, but panics if an error occurs. +func (_q *SubscriptionPlanQuery) AllX(ctx context.Context) []*SubscriptionPlan { + nodes, err := _q.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of SubscriptionPlan IDs. +func (_q *SubscriptionPlanQuery) IDs(ctx context.Context) (ids []int64, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(subscriptionplan.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (_q *SubscriptionPlanQuery) IDsX(ctx context.Context) []int64 { + ids, err := _q.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (_q *SubscriptionPlanQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, _q, querierCount[*SubscriptionPlanQuery](), _q.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (_q *SubscriptionPlanQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (_q *SubscriptionPlanQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (_q *SubscriptionPlanQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the SubscriptionPlanQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (_q *SubscriptionPlanQuery) Clone() *SubscriptionPlanQuery { + if _q == nil { + return nil + } + return &SubscriptionPlanQuery{ + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]subscriptionplan.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.SubscriptionPlan{}, _q.predicates...), + // clone intermediate query. + sql: _q.sql.Clone(), + path: _q.path, + } +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// GroupID int64 `json:"group_id,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.SubscriptionPlan.Query(). +// GroupBy(subscriptionplan.FieldGroupID). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (_q *SubscriptionPlanQuery) GroupBy(field string, fields ...string) *SubscriptionPlanGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &SubscriptionPlanGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields + grbuild.label = subscriptionplan.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// GroupID int64 `json:"group_id,omitempty"` +// } +// +// client.SubscriptionPlan.Query(). +// Select(subscriptionplan.FieldGroupID). +// Scan(ctx, &v) +func (_q *SubscriptionPlanQuery) Select(fields ...string) *SubscriptionPlanSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &SubscriptionPlanSelect{SubscriptionPlanQuery: _q} + sbuild.label = subscriptionplan.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a SubscriptionPlanSelect configured with the given aggregations. +func (_q *SubscriptionPlanQuery) Aggregate(fns ...AggregateFunc) *SubscriptionPlanSelect { + return _q.Select().Aggregate(fns...) +} + +func (_q *SubscriptionPlanQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { + if !subscriptionplan.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if _q.path != nil { + prev, err := _q.path(ctx) + if err != nil { + return err + } + _q.sql = prev + } + return nil +} + +func (_q *SubscriptionPlanQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*SubscriptionPlan, error) { + var ( + nodes = []*SubscriptionPlan{} + _spec = _q.querySpec() + ) + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*SubscriptionPlan).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &SubscriptionPlan{config: _q.config} + nodes = append(nodes, node) + return node.assignValues(columns, values) + } + if len(_q.modifiers) > 0 { + _spec.Modifiers = _q.modifiers + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + return nodes, nil +} + +func (_q *SubscriptionPlanQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + if len(_q.modifiers) > 0 { + _spec.Modifiers = _q.modifiers + } + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique + } + return sqlgraph.CountNodes(ctx, _q.driver, _spec) +} + +func (_q *SubscriptionPlanQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(subscriptionplan.Table, subscriptionplan.Columns, sqlgraph.NewFieldSpec(subscriptionplan.FieldID, field.TypeInt64)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true + } + if fields := _q.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, subscriptionplan.FieldID) + for i := range fields { + if fields[i] != subscriptionplan.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := _q.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := _q.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := _q.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := _q.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (_q *SubscriptionPlanQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) + t1 := builder.Table(subscriptionplan.Table) + columns := _q.ctx.Fields + if len(columns) == 0 { + columns = subscriptionplan.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if _q.sql != nil { + selector = _q.sql + selector.Select(selector.Columns(columns...)...) + } + if _q.ctx.Unique != nil && *_q.ctx.Unique { + selector.Distinct() + } + for _, m := range _q.modifiers { + m(selector) + } + for _, p := range _q.predicates { + p(selector) + } + for _, p := range _q.order { + p(selector) + } + if offset := _q.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := _q.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// ForUpdate locks the selected rows against concurrent updates, and prevent them from being +// updated, deleted or "selected ... for update" by other sessions, until the transaction is +// either committed or rolled-back. +func (_q *SubscriptionPlanQuery) ForUpdate(opts ...sql.LockOption) *SubscriptionPlanQuery { + if _q.driver.Dialect() == dialect.Postgres { + _q.Unique(false) + } + _q.modifiers = append(_q.modifiers, func(s *sql.Selector) { + s.ForUpdate(opts...) + }) + return _q +} + +// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock +// on any rows that are read. Other sessions can read the rows, but cannot modify them +// until your transaction commits. +func (_q *SubscriptionPlanQuery) ForShare(opts ...sql.LockOption) *SubscriptionPlanQuery { + if _q.driver.Dialect() == dialect.Postgres { + _q.Unique(false) + } + _q.modifiers = append(_q.modifiers, func(s *sql.Selector) { + s.ForShare(opts...) + }) + return _q +} + +// SubscriptionPlanGroupBy is the group-by builder for SubscriptionPlan entities. +type SubscriptionPlanGroupBy struct { + selector + build *SubscriptionPlanQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (_g *SubscriptionPlanGroupBy) Aggregate(fns ...AggregateFunc) *SubscriptionPlanGroupBy { + _g.fns = append(_g.fns, fns...) + return _g +} + +// Scan applies the selector query and scans the result into the given value. +func (_g *SubscriptionPlanGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*SubscriptionPlanQuery, *SubscriptionPlanGroupBy](ctx, _g.build, _g, _g.build.inters, v) +} + +func (_g *SubscriptionPlanGroupBy) sqlScan(ctx context.Context, root *SubscriptionPlanQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*_g.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// SubscriptionPlanSelect is the builder for selecting fields of SubscriptionPlan entities. +type SubscriptionPlanSelect struct { + *SubscriptionPlanQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *SubscriptionPlanSelect) Aggregate(fns ...AggregateFunc) *SubscriptionPlanSelect { + _s.fns = append(_s.fns, fns...) + return _s +} + +// Scan applies the selector query and scans the result into the given value. +func (_s *SubscriptionPlanSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*SubscriptionPlanQuery, *SubscriptionPlanSelect](ctx, _s.SubscriptionPlanQuery, _s, _s.inters, v) +} + +func (_s *SubscriptionPlanSelect) sqlScan(ctx context.Context, root *SubscriptionPlanQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/backend/ent/subscriptionplan_update.go b/backend/ent/subscriptionplan_update.go new file mode 100644 index 0000000000..c9225d0f7e --- /dev/null +++ b/backend/ent/subscriptionplan_update.go @@ -0,0 +1,750 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/predicate" + "github.com/Wei-Shaw/sub2api/ent/subscriptionplan" +) + +// SubscriptionPlanUpdate is the builder for updating SubscriptionPlan entities. +type SubscriptionPlanUpdate struct { + config + hooks []Hook + mutation *SubscriptionPlanMutation +} + +// Where appends a list predicates to the SubscriptionPlanUpdate builder. +func (_u *SubscriptionPlanUpdate) Where(ps ...predicate.SubscriptionPlan) *SubscriptionPlanUpdate { + _u.mutation.Where(ps...) + return _u +} + +// SetGroupID sets the "group_id" field. +func (_u *SubscriptionPlanUpdate) SetGroupID(v int64) *SubscriptionPlanUpdate { + _u.mutation.ResetGroupID() + _u.mutation.SetGroupID(v) + return _u +} + +// SetNillableGroupID sets the "group_id" field if the given value is not nil. +func (_u *SubscriptionPlanUpdate) SetNillableGroupID(v *int64) *SubscriptionPlanUpdate { + if v != nil { + _u.SetGroupID(*v) + } + return _u +} + +// AddGroupID adds value to the "group_id" field. +func (_u *SubscriptionPlanUpdate) AddGroupID(v int64) *SubscriptionPlanUpdate { + _u.mutation.AddGroupID(v) + return _u +} + +// SetName sets the "name" field. +func (_u *SubscriptionPlanUpdate) SetName(v string) *SubscriptionPlanUpdate { + _u.mutation.SetName(v) + return _u +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (_u *SubscriptionPlanUpdate) SetNillableName(v *string) *SubscriptionPlanUpdate { + if v != nil { + _u.SetName(*v) + } + return _u +} + +// SetDescription sets the "description" field. +func (_u *SubscriptionPlanUpdate) SetDescription(v string) *SubscriptionPlanUpdate { + _u.mutation.SetDescription(v) + return _u +} + +// SetNillableDescription sets the "description" field if the given value is not nil. +func (_u *SubscriptionPlanUpdate) SetNillableDescription(v *string) *SubscriptionPlanUpdate { + if v != nil { + _u.SetDescription(*v) + } + return _u +} + +// SetPrice sets the "price" field. +func (_u *SubscriptionPlanUpdate) SetPrice(v float64) *SubscriptionPlanUpdate { + _u.mutation.ResetPrice() + _u.mutation.SetPrice(v) + return _u +} + +// SetNillablePrice sets the "price" field if the given value is not nil. +func (_u *SubscriptionPlanUpdate) SetNillablePrice(v *float64) *SubscriptionPlanUpdate { + if v != nil { + _u.SetPrice(*v) + } + return _u +} + +// AddPrice adds value to the "price" field. +func (_u *SubscriptionPlanUpdate) AddPrice(v float64) *SubscriptionPlanUpdate { + _u.mutation.AddPrice(v) + return _u +} + +// SetOriginalPrice sets the "original_price" field. +func (_u *SubscriptionPlanUpdate) SetOriginalPrice(v float64) *SubscriptionPlanUpdate { + _u.mutation.ResetOriginalPrice() + _u.mutation.SetOriginalPrice(v) + return _u +} + +// SetNillableOriginalPrice sets the "original_price" field if the given value is not nil. +func (_u *SubscriptionPlanUpdate) SetNillableOriginalPrice(v *float64) *SubscriptionPlanUpdate { + if v != nil { + _u.SetOriginalPrice(*v) + } + return _u +} + +// AddOriginalPrice adds value to the "original_price" field. +func (_u *SubscriptionPlanUpdate) AddOriginalPrice(v float64) *SubscriptionPlanUpdate { + _u.mutation.AddOriginalPrice(v) + return _u +} + +// ClearOriginalPrice clears the value of the "original_price" field. +func (_u *SubscriptionPlanUpdate) ClearOriginalPrice() *SubscriptionPlanUpdate { + _u.mutation.ClearOriginalPrice() + return _u +} + +// SetValidityDays sets the "validity_days" field. +func (_u *SubscriptionPlanUpdate) SetValidityDays(v int) *SubscriptionPlanUpdate { + _u.mutation.ResetValidityDays() + _u.mutation.SetValidityDays(v) + return _u +} + +// SetNillableValidityDays sets the "validity_days" field if the given value is not nil. +func (_u *SubscriptionPlanUpdate) SetNillableValidityDays(v *int) *SubscriptionPlanUpdate { + if v != nil { + _u.SetValidityDays(*v) + } + return _u +} + +// AddValidityDays adds value to the "validity_days" field. +func (_u *SubscriptionPlanUpdate) AddValidityDays(v int) *SubscriptionPlanUpdate { + _u.mutation.AddValidityDays(v) + return _u +} + +// SetValidityUnit sets the "validity_unit" field. +func (_u *SubscriptionPlanUpdate) SetValidityUnit(v string) *SubscriptionPlanUpdate { + _u.mutation.SetValidityUnit(v) + return _u +} + +// SetNillableValidityUnit sets the "validity_unit" field if the given value is not nil. +func (_u *SubscriptionPlanUpdate) SetNillableValidityUnit(v *string) *SubscriptionPlanUpdate { + if v != nil { + _u.SetValidityUnit(*v) + } + return _u +} + +// SetFeatures sets the "features" field. +func (_u *SubscriptionPlanUpdate) SetFeatures(v string) *SubscriptionPlanUpdate { + _u.mutation.SetFeatures(v) + return _u +} + +// SetNillableFeatures sets the "features" field if the given value is not nil. +func (_u *SubscriptionPlanUpdate) SetNillableFeatures(v *string) *SubscriptionPlanUpdate { + if v != nil { + _u.SetFeatures(*v) + } + return _u +} + +// SetProductName sets the "product_name" field. +func (_u *SubscriptionPlanUpdate) SetProductName(v string) *SubscriptionPlanUpdate { + _u.mutation.SetProductName(v) + return _u +} + +// SetNillableProductName sets the "product_name" field if the given value is not nil. +func (_u *SubscriptionPlanUpdate) SetNillableProductName(v *string) *SubscriptionPlanUpdate { + if v != nil { + _u.SetProductName(*v) + } + return _u +} + +// SetForSale sets the "for_sale" field. +func (_u *SubscriptionPlanUpdate) SetForSale(v bool) *SubscriptionPlanUpdate { + _u.mutation.SetForSale(v) + return _u +} + +// SetNillableForSale sets the "for_sale" field if the given value is not nil. +func (_u *SubscriptionPlanUpdate) SetNillableForSale(v *bool) *SubscriptionPlanUpdate { + if v != nil { + _u.SetForSale(*v) + } + return _u +} + +// SetSortOrder sets the "sort_order" field. +func (_u *SubscriptionPlanUpdate) SetSortOrder(v int) *SubscriptionPlanUpdate { + _u.mutation.ResetSortOrder() + _u.mutation.SetSortOrder(v) + return _u +} + +// SetNillableSortOrder sets the "sort_order" field if the given value is not nil. +func (_u *SubscriptionPlanUpdate) SetNillableSortOrder(v *int) *SubscriptionPlanUpdate { + if v != nil { + _u.SetSortOrder(*v) + } + return _u +} + +// AddSortOrder adds value to the "sort_order" field. +func (_u *SubscriptionPlanUpdate) AddSortOrder(v int) *SubscriptionPlanUpdate { + _u.mutation.AddSortOrder(v) + return _u +} + +// SetUpdatedAt sets the "updated_at" field. +func (_u *SubscriptionPlanUpdate) SetUpdatedAt(v time.Time) *SubscriptionPlanUpdate { + _u.mutation.SetUpdatedAt(v) + return _u +} + +// Mutation returns the SubscriptionPlanMutation object of the builder. +func (_u *SubscriptionPlanUpdate) Mutation() *SubscriptionPlanMutation { + return _u.mutation +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (_u *SubscriptionPlanUpdate) Save(ctx context.Context) (int, error) { + _u.defaults() + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *SubscriptionPlanUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (_u *SubscriptionPlanUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *SubscriptionPlanUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_u *SubscriptionPlanUpdate) defaults() { + if _, ok := _u.mutation.UpdatedAt(); !ok { + v := subscriptionplan.UpdateDefaultUpdatedAt() + _u.mutation.SetUpdatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *SubscriptionPlanUpdate) check() error { + if v, ok := _u.mutation.Name(); ok { + if err := subscriptionplan.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "SubscriptionPlan.name": %w`, err)} + } + } + if v, ok := _u.mutation.ValidityUnit(); ok { + if err := subscriptionplan.ValidityUnitValidator(v); err != nil { + return &ValidationError{Name: "validity_unit", err: fmt.Errorf(`ent: validator failed for field "SubscriptionPlan.validity_unit": %w`, err)} + } + } + if v, ok := _u.mutation.ProductName(); ok { + if err := subscriptionplan.ProductNameValidator(v); err != nil { + return &ValidationError{Name: "product_name", err: fmt.Errorf(`ent: validator failed for field "SubscriptionPlan.product_name": %w`, err)} + } + } + return nil +} + +func (_u *SubscriptionPlanUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(subscriptionplan.Table, subscriptionplan.Columns, sqlgraph.NewFieldSpec(subscriptionplan.FieldID, field.TypeInt64)) + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.GroupID(); ok { + _spec.SetField(subscriptionplan.FieldGroupID, field.TypeInt64, value) + } + if value, ok := _u.mutation.AddedGroupID(); ok { + _spec.AddField(subscriptionplan.FieldGroupID, field.TypeInt64, value) + } + if value, ok := _u.mutation.Name(); ok { + _spec.SetField(subscriptionplan.FieldName, field.TypeString, value) + } + if value, ok := _u.mutation.Description(); ok { + _spec.SetField(subscriptionplan.FieldDescription, field.TypeString, value) + } + if value, ok := _u.mutation.Price(); ok { + _spec.SetField(subscriptionplan.FieldPrice, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedPrice(); ok { + _spec.AddField(subscriptionplan.FieldPrice, field.TypeFloat64, value) + } + if value, ok := _u.mutation.OriginalPrice(); ok { + _spec.SetField(subscriptionplan.FieldOriginalPrice, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedOriginalPrice(); ok { + _spec.AddField(subscriptionplan.FieldOriginalPrice, field.TypeFloat64, value) + } + if _u.mutation.OriginalPriceCleared() { + _spec.ClearField(subscriptionplan.FieldOriginalPrice, field.TypeFloat64) + } + if value, ok := _u.mutation.ValidityDays(); ok { + _spec.SetField(subscriptionplan.FieldValidityDays, field.TypeInt, value) + } + if value, ok := _u.mutation.AddedValidityDays(); ok { + _spec.AddField(subscriptionplan.FieldValidityDays, field.TypeInt, value) + } + if value, ok := _u.mutation.ValidityUnit(); ok { + _spec.SetField(subscriptionplan.FieldValidityUnit, field.TypeString, value) + } + if value, ok := _u.mutation.Features(); ok { + _spec.SetField(subscriptionplan.FieldFeatures, field.TypeString, value) + } + if value, ok := _u.mutation.ProductName(); ok { + _spec.SetField(subscriptionplan.FieldProductName, field.TypeString, value) + } + if value, ok := _u.mutation.ForSale(); ok { + _spec.SetField(subscriptionplan.FieldForSale, field.TypeBool, value) + } + if value, ok := _u.mutation.SortOrder(); ok { + _spec.SetField(subscriptionplan.FieldSortOrder, field.TypeInt, value) + } + if value, ok := _u.mutation.AddedSortOrder(); ok { + _spec.AddField(subscriptionplan.FieldSortOrder, field.TypeInt, value) + } + if value, ok := _u.mutation.UpdatedAt(); ok { + _spec.SetField(subscriptionplan.FieldUpdatedAt, field.TypeTime, value) + } + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{subscriptionplan.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + _u.mutation.done = true + return _node, nil +} + +// SubscriptionPlanUpdateOne is the builder for updating a single SubscriptionPlan entity. +type SubscriptionPlanUpdateOne struct { + config + fields []string + hooks []Hook + mutation *SubscriptionPlanMutation +} + +// SetGroupID sets the "group_id" field. +func (_u *SubscriptionPlanUpdateOne) SetGroupID(v int64) *SubscriptionPlanUpdateOne { + _u.mutation.ResetGroupID() + _u.mutation.SetGroupID(v) + return _u +} + +// SetNillableGroupID sets the "group_id" field if the given value is not nil. +func (_u *SubscriptionPlanUpdateOne) SetNillableGroupID(v *int64) *SubscriptionPlanUpdateOne { + if v != nil { + _u.SetGroupID(*v) + } + return _u +} + +// AddGroupID adds value to the "group_id" field. +func (_u *SubscriptionPlanUpdateOne) AddGroupID(v int64) *SubscriptionPlanUpdateOne { + _u.mutation.AddGroupID(v) + return _u +} + +// SetName sets the "name" field. +func (_u *SubscriptionPlanUpdateOne) SetName(v string) *SubscriptionPlanUpdateOne { + _u.mutation.SetName(v) + return _u +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (_u *SubscriptionPlanUpdateOne) SetNillableName(v *string) *SubscriptionPlanUpdateOne { + if v != nil { + _u.SetName(*v) + } + return _u +} + +// SetDescription sets the "description" field. +func (_u *SubscriptionPlanUpdateOne) SetDescription(v string) *SubscriptionPlanUpdateOne { + _u.mutation.SetDescription(v) + return _u +} + +// SetNillableDescription sets the "description" field if the given value is not nil. +func (_u *SubscriptionPlanUpdateOne) SetNillableDescription(v *string) *SubscriptionPlanUpdateOne { + if v != nil { + _u.SetDescription(*v) + } + return _u +} + +// SetPrice sets the "price" field. +func (_u *SubscriptionPlanUpdateOne) SetPrice(v float64) *SubscriptionPlanUpdateOne { + _u.mutation.ResetPrice() + _u.mutation.SetPrice(v) + return _u +} + +// SetNillablePrice sets the "price" field if the given value is not nil. +func (_u *SubscriptionPlanUpdateOne) SetNillablePrice(v *float64) *SubscriptionPlanUpdateOne { + if v != nil { + _u.SetPrice(*v) + } + return _u +} + +// AddPrice adds value to the "price" field. +func (_u *SubscriptionPlanUpdateOne) AddPrice(v float64) *SubscriptionPlanUpdateOne { + _u.mutation.AddPrice(v) + return _u +} + +// SetOriginalPrice sets the "original_price" field. +func (_u *SubscriptionPlanUpdateOne) SetOriginalPrice(v float64) *SubscriptionPlanUpdateOne { + _u.mutation.ResetOriginalPrice() + _u.mutation.SetOriginalPrice(v) + return _u +} + +// SetNillableOriginalPrice sets the "original_price" field if the given value is not nil. +func (_u *SubscriptionPlanUpdateOne) SetNillableOriginalPrice(v *float64) *SubscriptionPlanUpdateOne { + if v != nil { + _u.SetOriginalPrice(*v) + } + return _u +} + +// AddOriginalPrice adds value to the "original_price" field. +func (_u *SubscriptionPlanUpdateOne) AddOriginalPrice(v float64) *SubscriptionPlanUpdateOne { + _u.mutation.AddOriginalPrice(v) + return _u +} + +// ClearOriginalPrice clears the value of the "original_price" field. +func (_u *SubscriptionPlanUpdateOne) ClearOriginalPrice() *SubscriptionPlanUpdateOne { + _u.mutation.ClearOriginalPrice() + return _u +} + +// SetValidityDays sets the "validity_days" field. +func (_u *SubscriptionPlanUpdateOne) SetValidityDays(v int) *SubscriptionPlanUpdateOne { + _u.mutation.ResetValidityDays() + _u.mutation.SetValidityDays(v) + return _u +} + +// SetNillableValidityDays sets the "validity_days" field if the given value is not nil. +func (_u *SubscriptionPlanUpdateOne) SetNillableValidityDays(v *int) *SubscriptionPlanUpdateOne { + if v != nil { + _u.SetValidityDays(*v) + } + return _u +} + +// AddValidityDays adds value to the "validity_days" field. +func (_u *SubscriptionPlanUpdateOne) AddValidityDays(v int) *SubscriptionPlanUpdateOne { + _u.mutation.AddValidityDays(v) + return _u +} + +// SetValidityUnit sets the "validity_unit" field. +func (_u *SubscriptionPlanUpdateOne) SetValidityUnit(v string) *SubscriptionPlanUpdateOne { + _u.mutation.SetValidityUnit(v) + return _u +} + +// SetNillableValidityUnit sets the "validity_unit" field if the given value is not nil. +func (_u *SubscriptionPlanUpdateOne) SetNillableValidityUnit(v *string) *SubscriptionPlanUpdateOne { + if v != nil { + _u.SetValidityUnit(*v) + } + return _u +} + +// SetFeatures sets the "features" field. +func (_u *SubscriptionPlanUpdateOne) SetFeatures(v string) *SubscriptionPlanUpdateOne { + _u.mutation.SetFeatures(v) + return _u +} + +// SetNillableFeatures sets the "features" field if the given value is not nil. +func (_u *SubscriptionPlanUpdateOne) SetNillableFeatures(v *string) *SubscriptionPlanUpdateOne { + if v != nil { + _u.SetFeatures(*v) + } + return _u +} + +// SetProductName sets the "product_name" field. +func (_u *SubscriptionPlanUpdateOne) SetProductName(v string) *SubscriptionPlanUpdateOne { + _u.mutation.SetProductName(v) + return _u +} + +// SetNillableProductName sets the "product_name" field if the given value is not nil. +func (_u *SubscriptionPlanUpdateOne) SetNillableProductName(v *string) *SubscriptionPlanUpdateOne { + if v != nil { + _u.SetProductName(*v) + } + return _u +} + +// SetForSale sets the "for_sale" field. +func (_u *SubscriptionPlanUpdateOne) SetForSale(v bool) *SubscriptionPlanUpdateOne { + _u.mutation.SetForSale(v) + return _u +} + +// SetNillableForSale sets the "for_sale" field if the given value is not nil. +func (_u *SubscriptionPlanUpdateOne) SetNillableForSale(v *bool) *SubscriptionPlanUpdateOne { + if v != nil { + _u.SetForSale(*v) + } + return _u +} + +// SetSortOrder sets the "sort_order" field. +func (_u *SubscriptionPlanUpdateOne) SetSortOrder(v int) *SubscriptionPlanUpdateOne { + _u.mutation.ResetSortOrder() + _u.mutation.SetSortOrder(v) + return _u +} + +// SetNillableSortOrder sets the "sort_order" field if the given value is not nil. +func (_u *SubscriptionPlanUpdateOne) SetNillableSortOrder(v *int) *SubscriptionPlanUpdateOne { + if v != nil { + _u.SetSortOrder(*v) + } + return _u +} + +// AddSortOrder adds value to the "sort_order" field. +func (_u *SubscriptionPlanUpdateOne) AddSortOrder(v int) *SubscriptionPlanUpdateOne { + _u.mutation.AddSortOrder(v) + return _u +} + +// SetUpdatedAt sets the "updated_at" field. +func (_u *SubscriptionPlanUpdateOne) SetUpdatedAt(v time.Time) *SubscriptionPlanUpdateOne { + _u.mutation.SetUpdatedAt(v) + return _u +} + +// Mutation returns the SubscriptionPlanMutation object of the builder. +func (_u *SubscriptionPlanUpdateOne) Mutation() *SubscriptionPlanMutation { + return _u.mutation +} + +// Where appends a list predicates to the SubscriptionPlanUpdate builder. +func (_u *SubscriptionPlanUpdateOne) Where(ps ...predicate.SubscriptionPlan) *SubscriptionPlanUpdateOne { + _u.mutation.Where(ps...) + return _u +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (_u *SubscriptionPlanUpdateOne) Select(field string, fields ...string) *SubscriptionPlanUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u +} + +// Save executes the query and returns the updated SubscriptionPlan entity. +func (_u *SubscriptionPlanUpdateOne) Save(ctx context.Context) (*SubscriptionPlan, error) { + _u.defaults() + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *SubscriptionPlanUpdateOne) SaveX(ctx context.Context) *SubscriptionPlan { + node, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (_u *SubscriptionPlanUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *SubscriptionPlanUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_u *SubscriptionPlanUpdateOne) defaults() { + if _, ok := _u.mutation.UpdatedAt(); !ok { + v := subscriptionplan.UpdateDefaultUpdatedAt() + _u.mutation.SetUpdatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *SubscriptionPlanUpdateOne) check() error { + if v, ok := _u.mutation.Name(); ok { + if err := subscriptionplan.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "SubscriptionPlan.name": %w`, err)} + } + } + if v, ok := _u.mutation.ValidityUnit(); ok { + if err := subscriptionplan.ValidityUnitValidator(v); err != nil { + return &ValidationError{Name: "validity_unit", err: fmt.Errorf(`ent: validator failed for field "SubscriptionPlan.validity_unit": %w`, err)} + } + } + if v, ok := _u.mutation.ProductName(); ok { + if err := subscriptionplan.ProductNameValidator(v); err != nil { + return &ValidationError{Name: "product_name", err: fmt.Errorf(`ent: validator failed for field "SubscriptionPlan.product_name": %w`, err)} + } + } + return nil +} + +func (_u *SubscriptionPlanUpdateOne) sqlSave(ctx context.Context) (_node *SubscriptionPlan, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(subscriptionplan.Table, subscriptionplan.Columns, sqlgraph.NewFieldSpec(subscriptionplan.FieldID, field.TypeInt64)) + id, ok := _u.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "SubscriptionPlan.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := _u.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, subscriptionplan.FieldID) + for _, f := range fields { + if !subscriptionplan.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != subscriptionplan.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.GroupID(); ok { + _spec.SetField(subscriptionplan.FieldGroupID, field.TypeInt64, value) + } + if value, ok := _u.mutation.AddedGroupID(); ok { + _spec.AddField(subscriptionplan.FieldGroupID, field.TypeInt64, value) + } + if value, ok := _u.mutation.Name(); ok { + _spec.SetField(subscriptionplan.FieldName, field.TypeString, value) + } + if value, ok := _u.mutation.Description(); ok { + _spec.SetField(subscriptionplan.FieldDescription, field.TypeString, value) + } + if value, ok := _u.mutation.Price(); ok { + _spec.SetField(subscriptionplan.FieldPrice, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedPrice(); ok { + _spec.AddField(subscriptionplan.FieldPrice, field.TypeFloat64, value) + } + if value, ok := _u.mutation.OriginalPrice(); ok { + _spec.SetField(subscriptionplan.FieldOriginalPrice, field.TypeFloat64, value) + } + if value, ok := _u.mutation.AddedOriginalPrice(); ok { + _spec.AddField(subscriptionplan.FieldOriginalPrice, field.TypeFloat64, value) + } + if _u.mutation.OriginalPriceCleared() { + _spec.ClearField(subscriptionplan.FieldOriginalPrice, field.TypeFloat64) + } + if value, ok := _u.mutation.ValidityDays(); ok { + _spec.SetField(subscriptionplan.FieldValidityDays, field.TypeInt, value) + } + if value, ok := _u.mutation.AddedValidityDays(); ok { + _spec.AddField(subscriptionplan.FieldValidityDays, field.TypeInt, value) + } + if value, ok := _u.mutation.ValidityUnit(); ok { + _spec.SetField(subscriptionplan.FieldValidityUnit, field.TypeString, value) + } + if value, ok := _u.mutation.Features(); ok { + _spec.SetField(subscriptionplan.FieldFeatures, field.TypeString, value) + } + if value, ok := _u.mutation.ProductName(); ok { + _spec.SetField(subscriptionplan.FieldProductName, field.TypeString, value) + } + if value, ok := _u.mutation.ForSale(); ok { + _spec.SetField(subscriptionplan.FieldForSale, field.TypeBool, value) + } + if value, ok := _u.mutation.SortOrder(); ok { + _spec.SetField(subscriptionplan.FieldSortOrder, field.TypeInt, value) + } + if value, ok := _u.mutation.AddedSortOrder(); ok { + _spec.AddField(subscriptionplan.FieldSortOrder, field.TypeInt, value) + } + if value, ok := _u.mutation.UpdatedAt(); ok { + _spec.SetField(subscriptionplan.FieldUpdatedAt, field.TypeTime, value) + } + _node = &SubscriptionPlan{config: _u.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{subscriptionplan.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + _u.mutation.done = true + return _node, nil +} diff --git a/backend/ent/tx.go b/backend/ent/tx.go index b5aea44731..bb3139d5c8 100644 --- a/backend/ent/tx.go +++ b/backend/ent/tx.go @@ -30,6 +30,12 @@ type Tx struct { Group *GroupClient // IdempotencyRecord is the client for interacting with the IdempotencyRecord builders. IdempotencyRecord *IdempotencyRecordClient + // PaymentAuditLog is the client for interacting with the PaymentAuditLog builders. + PaymentAuditLog *PaymentAuditLogClient + // PaymentOrder is the client for interacting with the PaymentOrder builders. + PaymentOrder *PaymentOrderClient + // PaymentProviderInstance is the client for interacting with the PaymentProviderInstance builders. + PaymentProviderInstance *PaymentProviderInstanceClient // PromoCode is the client for interacting with the PromoCode builders. PromoCode *PromoCodeClient // PromoCodeUsage is the client for interacting with the PromoCodeUsage builders. @@ -42,6 +48,8 @@ type Tx struct { SecuritySecret *SecuritySecretClient // Setting is the client for interacting with the Setting builders. Setting *SettingClient + // SubscriptionPlan is the client for interacting with the SubscriptionPlan builders. + SubscriptionPlan *SubscriptionPlanClient // TLSFingerprintProfile is the client for interacting with the TLSFingerprintProfile builders. TLSFingerprintProfile *TLSFingerprintProfileClient // UsageCleanupTask is the client for interacting with the UsageCleanupTask builders. @@ -197,12 +205,16 @@ func (tx *Tx) init() { tx.ErrorPassthroughRule = NewErrorPassthroughRuleClient(tx.config) tx.Group = NewGroupClient(tx.config) tx.IdempotencyRecord = NewIdempotencyRecordClient(tx.config) + tx.PaymentAuditLog = NewPaymentAuditLogClient(tx.config) + tx.PaymentOrder = NewPaymentOrderClient(tx.config) + tx.PaymentProviderInstance = NewPaymentProviderInstanceClient(tx.config) tx.PromoCode = NewPromoCodeClient(tx.config) tx.PromoCodeUsage = NewPromoCodeUsageClient(tx.config) tx.Proxy = NewProxyClient(tx.config) tx.RedeemCode = NewRedeemCodeClient(tx.config) tx.SecuritySecret = NewSecuritySecretClient(tx.config) tx.Setting = NewSettingClient(tx.config) + tx.SubscriptionPlan = NewSubscriptionPlanClient(tx.config) tx.TLSFingerprintProfile = NewTLSFingerprintProfileClient(tx.config) tx.UsageCleanupTask = NewUsageCleanupTaskClient(tx.config) tx.UsageLog = NewUsageLogClient(tx.config) diff --git a/backend/ent/user.go b/backend/ent/user.go index 2435aa1b99..a0eef2ba05 100644 --- a/backend/ent/user.go +++ b/backend/ent/user.go @@ -71,11 +71,13 @@ type UserEdges struct { AttributeValues []*UserAttributeValue `json:"attribute_values,omitempty"` // PromoCodeUsages holds the value of the promo_code_usages edge. PromoCodeUsages []*PromoCodeUsage `json:"promo_code_usages,omitempty"` + // PaymentOrders holds the value of the payment_orders edge. + PaymentOrders []*PaymentOrder `json:"payment_orders,omitempty"` // UserAllowedGroups holds the value of the user_allowed_groups edge. UserAllowedGroups []*UserAllowedGroup `json:"user_allowed_groups,omitempty"` // loadedTypes holds the information for reporting if a // type was loaded (or requested) in eager-loading or not. - loadedTypes [10]bool + loadedTypes [11]bool } // APIKeysOrErr returns the APIKeys value or an error if the edge @@ -159,10 +161,19 @@ func (e UserEdges) PromoCodeUsagesOrErr() ([]*PromoCodeUsage, error) { return nil, &NotLoadedError{edge: "promo_code_usages"} } +// PaymentOrdersOrErr returns the PaymentOrders value or an error if the edge +// was not loaded in eager-loading. +func (e UserEdges) PaymentOrdersOrErr() ([]*PaymentOrder, error) { + if e.loadedTypes[9] { + return e.PaymentOrders, nil + } + return nil, &NotLoadedError{edge: "payment_orders"} +} + // UserAllowedGroupsOrErr returns the UserAllowedGroups value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) UserAllowedGroupsOrErr() ([]*UserAllowedGroup, error) { - if e.loadedTypes[9] { + if e.loadedTypes[10] { return e.UserAllowedGroups, nil } return nil, &NotLoadedError{edge: "user_allowed_groups"} @@ -349,6 +360,11 @@ func (_m *User) QueryPromoCodeUsages() *PromoCodeUsageQuery { return NewUserClient(_m.config).QueryPromoCodeUsages(_m) } +// QueryPaymentOrders queries the "payment_orders" edge of the User entity. +func (_m *User) QueryPaymentOrders() *PaymentOrderQuery { + return NewUserClient(_m.config).QueryPaymentOrders(_m) +} + // QueryUserAllowedGroups queries the "user_allowed_groups" edge of the User entity. func (_m *User) QueryUserAllowedGroups() *UserAllowedGroupQuery { return NewUserClient(_m.config).QueryUserAllowedGroups(_m) diff --git a/backend/ent/user/user.go b/backend/ent/user/user.go index ae9418ff07..338518a841 100644 --- a/backend/ent/user/user.go +++ b/backend/ent/user/user.go @@ -61,6 +61,8 @@ const ( EdgeAttributeValues = "attribute_values" // EdgePromoCodeUsages holds the string denoting the promo_code_usages edge name in mutations. EdgePromoCodeUsages = "promo_code_usages" + // EdgePaymentOrders holds the string denoting the payment_orders edge name in mutations. + EdgePaymentOrders = "payment_orders" // EdgeUserAllowedGroups holds the string denoting the user_allowed_groups edge name in mutations. EdgeUserAllowedGroups = "user_allowed_groups" // Table holds the table name of the user in the database. @@ -126,6 +128,13 @@ const ( PromoCodeUsagesInverseTable = "promo_code_usages" // PromoCodeUsagesColumn is the table column denoting the promo_code_usages relation/edge. PromoCodeUsagesColumn = "user_id" + // PaymentOrdersTable is the table that holds the payment_orders relation/edge. + PaymentOrdersTable = "payment_orders" + // PaymentOrdersInverseTable is the table name for the PaymentOrder entity. + // It exists in this package in order to avoid circular dependency with the "paymentorder" package. + PaymentOrdersInverseTable = "payment_orders" + // PaymentOrdersColumn is the table column denoting the payment_orders relation/edge. + PaymentOrdersColumn = "user_id" // UserAllowedGroupsTable is the table that holds the user_allowed_groups relation/edge. UserAllowedGroupsTable = "user_allowed_groups" // UserAllowedGroupsInverseTable is the table name for the UserAllowedGroup entity. @@ -414,6 +423,20 @@ func ByPromoCodeUsages(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { } } +// ByPaymentOrdersCount orders the results by payment_orders count. +func ByPaymentOrdersCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newPaymentOrdersStep(), opts...) + } +} + +// ByPaymentOrders orders the results by payment_orders terms. +func ByPaymentOrders(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newPaymentOrdersStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} + // ByUserAllowedGroupsCount orders the results by user_allowed_groups count. func ByUserAllowedGroupsCount(opts ...sql.OrderTermOption) OrderOption { return func(s *sql.Selector) { @@ -490,6 +513,13 @@ func newPromoCodeUsagesStep() *sqlgraph.Step { sqlgraph.Edge(sqlgraph.O2M, false, PromoCodeUsagesTable, PromoCodeUsagesColumn), ) } +func newPaymentOrdersStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(PaymentOrdersInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, PaymentOrdersTable, PaymentOrdersColumn), + ) +} func newUserAllowedGroupsStep() *sqlgraph.Step { return sqlgraph.NewStep( sqlgraph.From(Table, FieldID), diff --git a/backend/ent/user/where.go b/backend/ent/user/where.go index 1de6103702..b1d1000f14 100644 --- a/backend/ent/user/where.go +++ b/backend/ent/user/where.go @@ -1067,6 +1067,29 @@ func HasPromoCodeUsagesWith(preds ...predicate.PromoCodeUsage) predicate.User { }) } +// HasPaymentOrders applies the HasEdge predicate on the "payment_orders" edge. +func HasPaymentOrders() predicate.User { + return predicate.User(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, PaymentOrdersTable, PaymentOrdersColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasPaymentOrdersWith applies the HasEdge predicate on the "payment_orders" edge with a given conditions (other predicates). +func HasPaymentOrdersWith(preds ...predicate.PaymentOrder) predicate.User { + return predicate.User(func(s *sql.Selector) { + step := newPaymentOrdersStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + // HasUserAllowedGroups applies the HasEdge predicate on the "user_allowed_groups" edge. func HasUserAllowedGroups() predicate.User { return predicate.User(func(s *sql.Selector) { diff --git a/backend/ent/user_create.go b/backend/ent/user_create.go index f862a580c5..7f1c5df141 100644 --- a/backend/ent/user_create.go +++ b/backend/ent/user_create.go @@ -14,6 +14,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/announcementread" "github.com/Wei-Shaw/sub2api/ent/apikey" "github.com/Wei-Shaw/sub2api/ent/group" + "github.com/Wei-Shaw/sub2api/ent/paymentorder" "github.com/Wei-Shaw/sub2api/ent/promocodeusage" "github.com/Wei-Shaw/sub2api/ent/redeemcode" "github.com/Wei-Shaw/sub2api/ent/usagelog" @@ -345,6 +346,21 @@ func (_c *UserCreate) AddPromoCodeUsages(v ...*PromoCodeUsage) *UserCreate { return _c.AddPromoCodeUsageIDs(ids...) } +// AddPaymentOrderIDs adds the "payment_orders" edge to the PaymentOrder entity by IDs. +func (_c *UserCreate) AddPaymentOrderIDs(ids ...int64) *UserCreate { + _c.mutation.AddPaymentOrderIDs(ids...) + return _c +} + +// AddPaymentOrders adds the "payment_orders" edges to the PaymentOrder entity. +func (_c *UserCreate) AddPaymentOrders(v ...*PaymentOrder) *UserCreate { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _c.AddPaymentOrderIDs(ids...) +} + // Mutation returns the UserMutation object of the builder. func (_c *UserCreate) Mutation() *UserMutation { return _c.mutation @@ -718,6 +734,22 @@ func (_c *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) { } _spec.Edges = append(_spec.Edges, edge) } + if nodes := _c.mutation.PaymentOrdersIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.PaymentOrdersTable, + Columns: []string{user.PaymentOrdersColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } return _node, _spec } diff --git a/backend/ent/user_query.go b/backend/ent/user_query.go index 4b56e16f43..113d87aca2 100644 --- a/backend/ent/user_query.go +++ b/backend/ent/user_query.go @@ -16,6 +16,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/announcementread" "github.com/Wei-Shaw/sub2api/ent/apikey" "github.com/Wei-Shaw/sub2api/ent/group" + "github.com/Wei-Shaw/sub2api/ent/paymentorder" "github.com/Wei-Shaw/sub2api/ent/predicate" "github.com/Wei-Shaw/sub2api/ent/promocodeusage" "github.com/Wei-Shaw/sub2api/ent/redeemcode" @@ -42,6 +43,7 @@ type UserQuery struct { withUsageLogs *UsageLogQuery withAttributeValues *UserAttributeValueQuery withPromoCodeUsages *PromoCodeUsageQuery + withPaymentOrders *PaymentOrderQuery withUserAllowedGroups *UserAllowedGroupQuery modifiers []func(*sql.Selector) // intermediate query (i.e. traversal path). @@ -278,6 +280,28 @@ func (_q *UserQuery) QueryPromoCodeUsages() *PromoCodeUsageQuery { return query } +// QueryPaymentOrders chains the current query on the "payment_orders" edge. +func (_q *UserQuery) QueryPaymentOrders() *PaymentOrderQuery { + query := (&PaymentOrderClient{config: _q.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + selector := _q.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, selector), + sqlgraph.To(paymentorder.Table, paymentorder.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, user.PaymentOrdersTable, user.PaymentOrdersColumn), + ) + fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step) + return fromU, nil + } + return query +} + // QueryUserAllowedGroups chains the current query on the "user_allowed_groups" edge. func (_q *UserQuery) QueryUserAllowedGroups() *UserAllowedGroupQuery { query := (&UserAllowedGroupClient{config: _q.config}).Query() @@ -501,6 +525,7 @@ func (_q *UserQuery) Clone() *UserQuery { withUsageLogs: _q.withUsageLogs.Clone(), withAttributeValues: _q.withAttributeValues.Clone(), withPromoCodeUsages: _q.withPromoCodeUsages.Clone(), + withPaymentOrders: _q.withPaymentOrders.Clone(), withUserAllowedGroups: _q.withUserAllowedGroups.Clone(), // clone intermediate query. sql: _q.sql.Clone(), @@ -607,6 +632,17 @@ func (_q *UserQuery) WithPromoCodeUsages(opts ...func(*PromoCodeUsageQuery)) *Us return _q } +// WithPaymentOrders tells the query-builder to eager-load the nodes that are connected to +// the "payment_orders" edge. The optional arguments are used to configure the query builder of the edge. +func (_q *UserQuery) WithPaymentOrders(opts ...func(*PaymentOrderQuery)) *UserQuery { + query := (&PaymentOrderClient{config: _q.config}).Query() + for _, opt := range opts { + opt(query) + } + _q.withPaymentOrders = query + return _q +} + // WithUserAllowedGroups tells the query-builder to eager-load the nodes that are connected to // the "user_allowed_groups" edge. The optional arguments are used to configure the query builder of the edge. func (_q *UserQuery) WithUserAllowedGroups(opts ...func(*UserAllowedGroupQuery)) *UserQuery { @@ -696,7 +732,7 @@ func (_q *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e var ( nodes = []*User{} _spec = _q.querySpec() - loadedTypes = [10]bool{ + loadedTypes = [11]bool{ _q.withAPIKeys != nil, _q.withRedeemCodes != nil, _q.withSubscriptions != nil, @@ -706,6 +742,7 @@ func (_q *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e _q.withUsageLogs != nil, _q.withAttributeValues != nil, _q.withPromoCodeUsages != nil, + _q.withPaymentOrders != nil, _q.withUserAllowedGroups != nil, } ) @@ -795,6 +832,13 @@ func (_q *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e return nil, err } } + if query := _q.withPaymentOrders; query != nil { + if err := _q.loadPaymentOrders(ctx, query, nodes, + func(n *User) { n.Edges.PaymentOrders = []*PaymentOrder{} }, + func(n *User, e *PaymentOrder) { n.Edges.PaymentOrders = append(n.Edges.PaymentOrders, e) }); err != nil { + return nil, err + } + } if query := _q.withUserAllowedGroups; query != nil { if err := _q.loadUserAllowedGroups(ctx, query, nodes, func(n *User) { n.Edges.UserAllowedGroups = []*UserAllowedGroup{} }, @@ -1112,6 +1156,36 @@ func (_q *UserQuery) loadPromoCodeUsages(ctx context.Context, query *PromoCodeUs } return nil } +func (_q *UserQuery) loadPaymentOrders(ctx context.Context, query *PaymentOrderQuery, nodes []*User, init func(*User), assign func(*User, *PaymentOrder)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[int64]*User) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } + } + if len(query.ctx.Fields) > 0 { + query.ctx.AppendFieldOnce(paymentorder.FieldUserID) + } + query.Where(predicate.PaymentOrder(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(user.PaymentOrdersColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.UserID + node, ok := nodeids[fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "user_id" returned %v for node %v`, fk, n.ID) + } + assign(node, n) + } + return nil +} func (_q *UserQuery) loadUserAllowedGroups(ctx context.Context, query *UserAllowedGroupQuery, nodes []*User, init func(*User), assign func(*User, *UserAllowedGroup)) error { fks := make([]driver.Value, 0, len(nodes)) nodeids := make(map[int64]*User) diff --git a/backend/ent/user_update.go b/backend/ent/user_update.go index 80222c92dc..8107c980a8 100644 --- a/backend/ent/user_update.go +++ b/backend/ent/user_update.go @@ -14,6 +14,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/announcementread" "github.com/Wei-Shaw/sub2api/ent/apikey" "github.com/Wei-Shaw/sub2api/ent/group" + "github.com/Wei-Shaw/sub2api/ent/paymentorder" "github.com/Wei-Shaw/sub2api/ent/predicate" "github.com/Wei-Shaw/sub2api/ent/promocodeusage" "github.com/Wei-Shaw/sub2api/ent/redeemcode" @@ -377,6 +378,21 @@ func (_u *UserUpdate) AddPromoCodeUsages(v ...*PromoCodeUsage) *UserUpdate { return _u.AddPromoCodeUsageIDs(ids...) } +// AddPaymentOrderIDs adds the "payment_orders" edge to the PaymentOrder entity by IDs. +func (_u *UserUpdate) AddPaymentOrderIDs(ids ...int64) *UserUpdate { + _u.mutation.AddPaymentOrderIDs(ids...) + return _u +} + +// AddPaymentOrders adds the "payment_orders" edges to the PaymentOrder entity. +func (_u *UserUpdate) AddPaymentOrders(v ...*PaymentOrder) *UserUpdate { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.AddPaymentOrderIDs(ids...) +} + // Mutation returns the UserMutation object of the builder. func (_u *UserUpdate) Mutation() *UserMutation { return _u.mutation @@ -571,6 +587,27 @@ func (_u *UserUpdate) RemovePromoCodeUsages(v ...*PromoCodeUsage) *UserUpdate { return _u.RemovePromoCodeUsageIDs(ids...) } +// ClearPaymentOrders clears all "payment_orders" edges to the PaymentOrder entity. +func (_u *UserUpdate) ClearPaymentOrders() *UserUpdate { + _u.mutation.ClearPaymentOrders() + return _u +} + +// RemovePaymentOrderIDs removes the "payment_orders" edge to PaymentOrder entities by IDs. +func (_u *UserUpdate) RemovePaymentOrderIDs(ids ...int64) *UserUpdate { + _u.mutation.RemovePaymentOrderIDs(ids...) + return _u +} + +// RemovePaymentOrders removes "payment_orders" edges to PaymentOrder entities. +func (_u *UserUpdate) RemovePaymentOrders(v ...*PaymentOrder) *UserUpdate { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.RemovePaymentOrderIDs(ids...) +} + // Save executes the query and returns the number of nodes affected by the update operation. func (_u *UserUpdate) Save(ctx context.Context) (int, error) { if err := _u.defaults(); err != nil { @@ -1126,6 +1163,51 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if _u.mutation.PaymentOrdersCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.PaymentOrdersTable, + Columns: []string{user.PaymentOrdersColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.RemovedPaymentOrdersIDs(); len(nodes) > 0 && !_u.mutation.PaymentOrdersCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.PaymentOrdersTable, + Columns: []string{user.PaymentOrdersColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.PaymentOrdersIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.PaymentOrdersTable, + Columns: []string{user.PaymentOrdersColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{user.Label} @@ -1487,6 +1569,21 @@ func (_u *UserUpdateOne) AddPromoCodeUsages(v ...*PromoCodeUsage) *UserUpdateOne return _u.AddPromoCodeUsageIDs(ids...) } +// AddPaymentOrderIDs adds the "payment_orders" edge to the PaymentOrder entity by IDs. +func (_u *UserUpdateOne) AddPaymentOrderIDs(ids ...int64) *UserUpdateOne { + _u.mutation.AddPaymentOrderIDs(ids...) + return _u +} + +// AddPaymentOrders adds the "payment_orders" edges to the PaymentOrder entity. +func (_u *UserUpdateOne) AddPaymentOrders(v ...*PaymentOrder) *UserUpdateOne { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.AddPaymentOrderIDs(ids...) +} + // Mutation returns the UserMutation object of the builder. func (_u *UserUpdateOne) Mutation() *UserMutation { return _u.mutation @@ -1681,6 +1778,27 @@ func (_u *UserUpdateOne) RemovePromoCodeUsages(v ...*PromoCodeUsage) *UserUpdate return _u.RemovePromoCodeUsageIDs(ids...) } +// ClearPaymentOrders clears all "payment_orders" edges to the PaymentOrder entity. +func (_u *UserUpdateOne) ClearPaymentOrders() *UserUpdateOne { + _u.mutation.ClearPaymentOrders() + return _u +} + +// RemovePaymentOrderIDs removes the "payment_orders" edge to PaymentOrder entities by IDs. +func (_u *UserUpdateOne) RemovePaymentOrderIDs(ids ...int64) *UserUpdateOne { + _u.mutation.RemovePaymentOrderIDs(ids...) + return _u +} + +// RemovePaymentOrders removes "payment_orders" edges to PaymentOrder entities. +func (_u *UserUpdateOne) RemovePaymentOrders(v ...*PaymentOrder) *UserUpdateOne { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.RemovePaymentOrderIDs(ids...) +} + // Where appends a list predicates to the UserUpdate builder. func (_u *UserUpdateOne) Where(ps ...predicate.User) *UserUpdateOne { _u.mutation.Where(ps...) @@ -2266,6 +2384,51 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if _u.mutation.PaymentOrdersCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.PaymentOrdersTable, + Columns: []string{user.PaymentOrdersColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.RemovedPaymentOrdersIDs(); len(nodes) > 0 && !_u.mutation.PaymentOrdersCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.PaymentOrdersTable, + Columns: []string{user.PaymentOrdersColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.PaymentOrdersIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.PaymentOrdersTable, + Columns: []string{user.PaymentOrdersColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(paymentorder.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } _node = &User{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues diff --git a/backend/go.mod b/backend/go.mod index bc296174d0..f316b72e03 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -155,12 +155,18 @@ require ( github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/smartwalle/alipay/v3 v3.2.29 // indirect + github.com/smartwalle/ncrypto v1.0.4 // indirect + github.com/smartwalle/ngx v1.1.0 // indirect + github.com/smartwalle/nsign v1.0.9 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stripe/stripe-go/v82 v82.5.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5 // indirect github.com/testcontainers/testcontainers-go v0.40.0 // indirect @@ -170,6 +176,7 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect + github.com/wechatpay-apiv3/wechatpay-go v0.2.21 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zclconf/go-cty v1.14.4 // indirect github.com/zclconf/go-cty-yaml v1.1.0 // indirect diff --git a/backend/go.sum b/backend/go.sum index 288679da37..79a9bd0f2b 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -20,6 +20,7 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw= github.com/alitto/pond/v2 v2.6.2 h1:Sphe40g0ILeM1pA2c2K+Th0DGU+pt0A/Kprr+WB24Pw= github.com/alitto/pond/v2 v2.6.2/go.mod h1:xkjYEgQ05RSpWdfSd1nM3OVv7TBhLdy7rMp3+2Nq+yE= github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= @@ -217,6 +218,8 @@ github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17k github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -361,8 +364,18 @@ github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/shirou/gopsutil/v4 v4.25.6 h1:kLysI2JsKorfaFPcYmcJqbzROzsBWEOAtw6A7dIfqXs= github.com/shirou/gopsutil/v4 v4.25.6/go.mod h1:PfybzyydfZcN+JMMjkF6Zb8Mq1A/VcogFFg7hj50W9c= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/smartwalle/alipay/v3 v3.2.29 h1:roGFqlml8hDa//0TpFmlyxZhndTYs7rbYLu/HlNFNJo= +github.com/smartwalle/alipay/v3 v3.2.29/go.mod h1:XarBLuAkwK3ah7mYjVtghRu+ysxzlex9sRkgqNMzMRU= +github.com/smartwalle/ncrypto v1.0.4 h1:P2rqQxDepJwgeO5ShoC+wGcK2wNJDmcdBOWAksuIgx8= +github.com/smartwalle/ncrypto v1.0.4/go.mod h1:Dwlp6sfeNaPMnOxMNayMTacvC5JGEVln3CVdiVDgbBk= +github.com/smartwalle/ngx v1.1.0 h1:q8nANgWSPRGeI/u+ixBoA4mf68DrUq6vZ+n9L5UKv9I= +github.com/smartwalle/ngx v1.1.0/go.mod h1:mx/nz2Pk5j+RBs7t6u6k22MPiBG/8CtOMpCnALIG8Y0= +github.com/smartwalle/nsign v1.0.9 h1:8poAgG7zBd8HkZy9RQDwasC6XZvJpDGQWSjzL2FZL6E= +github.com/smartwalle/nsign v1.0.9/go.mod h1:eY6I4CJlyNdVMP+t6z1H6Jpd4m5/V+8xi44ufSTxXgc= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= @@ -392,6 +405,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/stripe/stripe-go/v82 v82.5.1 h1:05q6ZDKoe8PLMpQV072obF74HCgP4XJeJYoNuRSX2+8= +github.com/stripe/stripe-go/v82 v82.5.1/go.mod h1:majCQX6AfObAvJiHraPi/5udwHi4ojRvJnnxckvHrX8= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5 h1:YqAladjX7xpA6BM04leXMWAEjS0mTZ5kUU9KRBriQJc= @@ -419,6 +434,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/wechatpay-apiv3/wechatpay-go v0.2.21 h1:uIyMpzvcaHA33W/QPtHstccw+X52HO1gFdvVL9O6Lfs= +github.com/wechatpay-apiv3/wechatpay-go v0.2.21/go.mod h1:A254AUBVB6R+EqQFo3yTgeh7HtyqRRtN2w9hQSOrd4Q= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= diff --git a/backend/internal/handler/admin/channel_handler.go b/backend/internal/handler/admin/channel_handler.go index b503e5c36e..f08f45577f 100644 --- a/backend/internal/handler/admin/channel_handler.go +++ b/backend/internal/handler/admin/channel_handler.go @@ -33,6 +33,7 @@ type createChannelRequest struct { ModelMapping map[string]map[string]string `json:"model_mapping"` BillingModelSource string `json:"billing_model_source" binding:"omitempty,oneof=requested upstream channel_mapped"` RestrictModels bool `json:"restrict_models"` + Features string `json:"features"` } type updateChannelRequest struct { @@ -44,6 +45,7 @@ type updateChannelRequest struct { ModelMapping map[string]map[string]string `json:"model_mapping"` BillingModelSource string `json:"billing_model_source" binding:"omitempty,oneof=requested upstream channel_mapped"` RestrictModels *bool `json:"restrict_models"` + Features *string `json:"features"` } type channelModelPricingRequest struct { @@ -78,6 +80,7 @@ type channelResponse struct { Status string `json:"status"` BillingModelSource string `json:"billing_model_source"` RestrictModels bool `json:"restrict_models"` + Features string `json:"features"` GroupIDs []int64 `json:"group_ids"` ModelPricing []channelModelPricingResponse `json:"model_pricing"` ModelMapping map[string]map[string]string `json:"model_mapping"` @@ -122,6 +125,7 @@ func channelToResponse(ch *service.Channel) *channelResponse { Description: ch.Description, Status: ch.Status, RestrictModels: ch.RestrictModels, + Features: ch.Features, GroupIDs: ch.GroupIDs, ModelMapping: ch.ModelMapping, CreatedAt: ch.CreatedAt.Format("2006-01-02T15:04:05Z"), @@ -295,6 +299,7 @@ func (h *ChannelHandler) Create(c *gin.Context) { ModelMapping: req.ModelMapping, BillingModelSource: req.BillingModelSource, RestrictModels: req.RestrictModels, + Features: req.Features, }) if err != nil { response.ErrorFrom(c, err) @@ -327,6 +332,7 @@ func (h *ChannelHandler) Update(c *gin.Context) { ModelMapping: req.ModelMapping, BillingModelSource: req.BillingModelSource, RestrictModels: req.RestrictModels, + Features: req.Features, } if req.ModelPricing != nil { pricing := pricingRequestToService(*req.ModelPricing) diff --git a/backend/internal/handler/admin/payment_handler.go b/backend/internal/handler/admin/payment_handler.go new file mode 100644 index 0000000000..4a773e0c52 --- /dev/null +++ b/backend/internal/handler/admin/payment_handler.go @@ -0,0 +1,316 @@ +package admin + +import ( + "strconv" + + "github.com/Wei-Shaw/sub2api/internal/pkg/response" + "github.com/Wei-Shaw/sub2api/internal/service" + + "github.com/gin-gonic/gin" +) + +// PaymentHandler handles admin payment management. +type PaymentHandler struct { + paymentService *service.PaymentService + configService *service.PaymentConfigService +} + +// NewPaymentHandler creates a new admin PaymentHandler. +func NewPaymentHandler(paymentService *service.PaymentService, configService *service.PaymentConfigService) *PaymentHandler { + return &PaymentHandler{ + paymentService: paymentService, + configService: configService, + } +} + +// --- Dashboard --- + +// GetDashboard returns payment dashboard statistics. +// GET /api/v1/admin/payment/dashboard +func (h *PaymentHandler) GetDashboard(c *gin.Context) { + days := 30 + if d := c.Query("days"); d != "" { + if v, err := strconv.Atoi(d); err == nil && v > 0 { + days = v + } + } + stats, err := h.paymentService.GetDashboardStats(c.Request.Context(), days) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, stats) +} + +// --- Orders --- + +// ListOrders returns a paginated list of all payment orders. +// GET /api/v1/admin/payment/orders +func (h *PaymentHandler) ListOrders(c *gin.Context) { + page, pageSize := response.ParsePagination(c) + var userID int64 + if uid := c.Query("user_id"); uid != "" { + if v, err := strconv.ParseInt(uid, 10, 64); err == nil { + userID = v + } + } + orders, total, err := h.paymentService.AdminListOrders(c.Request.Context(), userID, service.OrderListParams{ + Page: page, + PageSize: pageSize, + Status: c.Query("status"), + OrderType: c.Query("order_type"), + PaymentType: c.Query("payment_type"), + }) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Paginated(c, orders, int64(total), page, pageSize) +} + +// GetOrderDetail returns detailed information about a single order. +// GET /api/v1/admin/payment/orders/:id +func (h *PaymentHandler) GetOrderDetail(c *gin.Context) { + orderID, err := strconv.ParseInt(c.Param("id"), 10, 64) + if err != nil { + response.BadRequest(c, "Invalid order ID") + return + } + order, err := h.paymentService.GetOrderByID(c.Request.Context(), orderID) + if err != nil { + response.ErrorFrom(c, err) + return + } + auditLogs, _ := h.paymentService.GetOrderAuditLogs(c.Request.Context(), orderID) + response.Success(c, gin.H{"order": order, "auditLogs": auditLogs}) +} + +// CancelOrder cancels a pending order (admin). +// POST /api/v1/admin/payment/orders/:id/cancel +func (h *PaymentHandler) CancelOrder(c *gin.Context) { + orderID, err := strconv.ParseInt(c.Param("id"), 10, 64) + if err != nil { + response.BadRequest(c, "Invalid order ID") + return + } + msg, err := h.paymentService.AdminCancelOrder(c.Request.Context(), orderID) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, gin.H{"message": msg}) +} + +// RetryFulfillment retries fulfillment for a paid order. +// POST /api/v1/admin/payment/orders/:id/retry +func (h *PaymentHandler) RetryFulfillment(c *gin.Context) { + orderID, err := strconv.ParseInt(c.Param("id"), 10, 64) + if err != nil { + response.BadRequest(c, "Invalid order ID") + return + } + if err := h.paymentService.RetryFulfillment(c.Request.Context(), orderID); err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, gin.H{"message": "fulfillment retried"}) +} + +// AdminProcessRefundRequest is the request body for admin refund processing. +type AdminProcessRefundRequest struct { + Amount float64 `json:"amount"` + Reason string `json:"reason"` + Force bool `json:"force"` + DeductBalance bool `json:"deductBalance"` +} + +// ProcessRefund processes a refund for an order (admin). +// POST /api/v1/admin/payment/orders/:id/refund +func (h *PaymentHandler) ProcessRefund(c *gin.Context) { + orderID, err := strconv.ParseInt(c.Param("id"), 10, 64) + if err != nil { + response.BadRequest(c, "Invalid order ID") + return + } + + var req AdminProcessRefundRequest + if err := c.ShouldBindJSON(&req); err != nil { + response.BadRequest(c, "Invalid request: "+err.Error()) + return + } + + plan, earlyResult, err := h.paymentService.PrepareRefund(c.Request.Context(), orderID, req.Amount, req.Reason, req.Force, req.DeductBalance) + if err != nil { + response.ErrorFrom(c, err) + return + } + if earlyResult != nil { + response.Success(c, earlyResult) + return + } + + result, err := h.paymentService.ExecuteRefund(c.Request.Context(), plan) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, result) +} + +// --- Subscription Plans --- + +// ListPlans returns all subscription plans. +// GET /api/v1/admin/payment/plans +func (h *PaymentHandler) ListPlans(c *gin.Context) { + plans, err := h.configService.ListPlans(c.Request.Context()) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, plans) +} + +// CreatePlan creates a new subscription plan. +// POST /api/v1/admin/payment/plans +func (h *PaymentHandler) CreatePlan(c *gin.Context) { + var req service.CreatePlanRequest + if err := c.ShouldBindJSON(&req); err != nil { + response.BadRequest(c, "Invalid request: "+err.Error()) + return + } + plan, err := h.configService.CreatePlan(c.Request.Context(), req) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Created(c, plan) +} + +// UpdatePlan updates an existing subscription plan. +// PUT /api/v1/admin/payment/plans/:id +func (h *PaymentHandler) UpdatePlan(c *gin.Context) { + id, err := strconv.ParseInt(c.Param("id"), 10, 64) + if err != nil { + response.BadRequest(c, "Invalid plan ID") + return + } + var req service.UpdatePlanRequest + if err := c.ShouldBindJSON(&req); err != nil { + response.BadRequest(c, "Invalid request: "+err.Error()) + return + } + plan, err := h.configService.UpdatePlan(c.Request.Context(), id, req) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, plan) +} + +// DeletePlan deletes a subscription plan. +// DELETE /api/v1/admin/payment/plans/:id +func (h *PaymentHandler) DeletePlan(c *gin.Context) { + id, err := strconv.ParseInt(c.Param("id"), 10, 64) + if err != nil { + response.BadRequest(c, "Invalid plan ID") + return + } + if err := h.configService.DeletePlan(c.Request.Context(), id); err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, gin.H{"message": "deleted"}) +} + +// --- Provider Instances --- + +// ListProviders returns all payment provider instances. +// GET /api/v1/admin/payment/providers +func (h *PaymentHandler) ListProviders(c *gin.Context) { + providers, err := h.configService.ListProviderInstances(c.Request.Context()) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, providers) +} + +// CreateProvider creates a new payment provider instance. +// POST /api/v1/admin/payment/providers +func (h *PaymentHandler) CreateProvider(c *gin.Context) { + var req service.CreateProviderInstanceRequest + if err := c.ShouldBindJSON(&req); err != nil { + response.BadRequest(c, "Invalid request: "+err.Error()) + return + } + inst, err := h.configService.CreateProviderInstance(c.Request.Context(), req) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Created(c, inst) +} + +// UpdateProvider updates an existing payment provider instance. +// PUT /api/v1/admin/payment/providers/:id +func (h *PaymentHandler) UpdateProvider(c *gin.Context) { + id, err := strconv.ParseInt(c.Param("id"), 10, 64) + if err != nil { + response.BadRequest(c, "Invalid provider ID") + return + } + var req service.UpdateProviderInstanceRequest + if err := c.ShouldBindJSON(&req); err != nil { + response.BadRequest(c, "Invalid request: "+err.Error()) + return + } + inst, err := h.configService.UpdateProviderInstance(c.Request.Context(), id, req) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, inst) +} + +// DeleteProvider deletes a payment provider instance. +// DELETE /api/v1/admin/payment/providers/:id +func (h *PaymentHandler) DeleteProvider(c *gin.Context) { + id, err := strconv.ParseInt(c.Param("id"), 10, 64) + if err != nil { + response.BadRequest(c, "Invalid provider ID") + return + } + if err := h.configService.DeleteProviderInstance(c.Request.Context(), id); err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, gin.H{"message": "deleted"}) +} + +// --- Config --- + +// GetConfig returns the payment configuration (admin view). +// GET /api/v1/admin/payment/config +func (h *PaymentHandler) GetConfig(c *gin.Context) { + cfg, err := h.configService.GetPaymentConfig(c.Request.Context()) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, cfg) +} + +// UpdateConfig updates the payment configuration. +// PUT /api/v1/admin/payment/config +func (h *PaymentHandler) UpdateConfig(c *gin.Context) { + var req service.UpdatePaymentConfigRequest + if err := c.ShouldBindJSON(&req); err != nil { + response.BadRequest(c, "Invalid request: "+err.Error()) + return + } + if err := h.configService.UpdatePaymentConfig(c.Request.Context(), req); err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, gin.H{"message": "updated"}) +} diff --git a/backend/internal/handler/handler.go b/backend/internal/handler/handler.go index d4c349fb65..906a74f148 100644 --- a/backend/internal/handler/handler.go +++ b/backend/internal/handler/handler.go @@ -31,22 +31,25 @@ type AdminHandlers struct { APIKey *admin.AdminAPIKeyHandler ScheduledTest *admin.ScheduledTestHandler Channel *admin.ChannelHandler + Payment *admin.PaymentHandler } // Handlers contains all HTTP handlers type Handlers struct { - Auth *AuthHandler - User *UserHandler - APIKey *APIKeyHandler - Usage *UsageHandler - Redeem *RedeemHandler - Subscription *SubscriptionHandler - Announcement *AnnouncementHandler - Admin *AdminHandlers - Gateway *GatewayHandler - OpenAIGateway *OpenAIGatewayHandler - Setting *SettingHandler - Totp *TotpHandler + Auth *AuthHandler + User *UserHandler + APIKey *APIKeyHandler + Usage *UsageHandler + Redeem *RedeemHandler + Subscription *SubscriptionHandler + Announcement *AnnouncementHandler + Admin *AdminHandlers + Gateway *GatewayHandler + OpenAIGateway *OpenAIGatewayHandler + Setting *SettingHandler + Totp *TotpHandler + Payment *PaymentHandler + PaymentWebhook *PaymentWebhookHandler } // BuildInfo contains build-time information diff --git a/backend/internal/handler/payment_handler.go b/backend/internal/handler/payment_handler.go new file mode 100644 index 0000000000..cee80e72b8 --- /dev/null +++ b/backend/internal/handler/payment_handler.go @@ -0,0 +1,228 @@ +package handler + +import ( + "strconv" + "strings" + + "github.com/Wei-Shaw/sub2api/internal/pkg/response" + middleware2 "github.com/Wei-Shaw/sub2api/internal/server/middleware" + "github.com/Wei-Shaw/sub2api/internal/pkg/pagination" + "github.com/Wei-Shaw/sub2api/internal/service" + + "github.com/gin-gonic/gin" +) + +// PaymentHandler handles user-facing payment requests. +type PaymentHandler struct { + channelService *service.ChannelService + paymentService *service.PaymentService + configService *service.PaymentConfigService +} + +// NewPaymentHandler creates a new PaymentHandler. +func NewPaymentHandler(paymentService *service.PaymentService, configService *service.PaymentConfigService, channelService *service.ChannelService) *PaymentHandler { + return &PaymentHandler{ + channelService: channelService, + paymentService: paymentService, + configService: configService, + } +} + +// GetPaymentConfig returns the payment system configuration. +// GET /api/v1/payment/config +func (h *PaymentHandler) GetPaymentConfig(c *gin.Context) { + cfg, err := h.configService.GetPaymentConfig(c.Request.Context()) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, cfg) +} + +// GetPlans returns subscription plans available for sale. +// GET /api/v1/payment/plans +func (h *PaymentHandler) GetPlans(c *gin.Context) { + plans, err := h.configService.ListPlansForSale(c.Request.Context()) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, plans) +} + +// GetChannels returns enabled payment channels. +// GET /api/v1/payment/channels +func (h *PaymentHandler) GetChannels(c *gin.Context) { + channels, _, err := h.channelService.List(c.Request.Context(), pagination.PaginationParams{Page: 1, PageSize: 1000}, "active", "") + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, channels) +} + +// GetLimits returns per-payment-type limits. +// GET /api/v1/payment/limits +func (h *PaymentHandler) GetLimits(c *gin.Context) { + cfg, err := h.configService.GetPaymentConfig(c.Request.Context()) + if err != nil { + response.ErrorFrom(c, err) + return + } + limits, err := h.configService.GetMethodLimits(c.Request.Context(), cfg.EnabledTypes) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, limits) +} + +// CreateOrderRequest is the request body for creating a payment order. +type CreateOrderRequest struct { + Amount float64 `json:"amount"` + PaymentType string `json:"paymentType" binding:"required"` + OrderType string `json:"orderType"` + PlanID int64 `json:"planId"` +} + +// CreateOrder creates a new payment order. +// POST /api/v1/payment/orders +func (h *PaymentHandler) CreateOrder(c *gin.Context) { + subject, ok := middleware2.GetAuthSubjectFromContext(c) + if !ok { + response.Unauthorized(c, "User not authenticated") + return + } + + var req CreateOrderRequest + if err := c.ShouldBindJSON(&req); err != nil { + response.BadRequest(c, "Invalid request: "+err.Error()) + return + } + + result, err := h.paymentService.CreateOrder(c.Request.Context(), service.CreateOrderRequest{ + UserID: subject.UserID, + Amount: req.Amount, + PaymentType: req.PaymentType, + ClientIP: c.ClientIP(), + IsMobile: isMobile(c), + SrcHost: c.Request.Host, + SrcURL: c.Request.Referer(), + OrderType: req.OrderType, + PlanID: req.PlanID, + }) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, result) +} + +// GetMyOrders returns the authenticated user's orders. +// GET /api/v1/payment/orders/my +func (h *PaymentHandler) GetMyOrders(c *gin.Context) { + subject, ok := middleware2.GetAuthSubjectFromContext(c) + if !ok { + response.Unauthorized(c, "User not authenticated") + return + } + + page, pageSize := response.ParsePagination(c) + orders, total, err := h.paymentService.GetUserOrders(c.Request.Context(), subject.UserID, service.OrderListParams{ + Page: page, + PageSize: pageSize, + Status: c.Query("status"), + OrderType: c.Query("order_type"), + PaymentType: c.Query("payment_type"), + }) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Paginated(c, orders, int64(total), page, pageSize) +} + +// GetOrder returns a single order for the authenticated user. +// GET /api/v1/payment/orders/:id +func (h *PaymentHandler) GetOrder(c *gin.Context) { + subject, ok := middleware2.GetAuthSubjectFromContext(c) + if !ok { + response.Unauthorized(c, "User not authenticated") + return + } + + orderID, err := strconv.ParseInt(c.Param("id"), 10, 64) + if err != nil { + response.BadRequest(c, "Invalid order ID") + return + } + + order, err := h.paymentService.GetOrder(c.Request.Context(), orderID, subject.UserID) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, order) +} + +// CancelOrder cancels a pending order for the authenticated user. +// POST /api/v1/payment/orders/:id/cancel +func (h *PaymentHandler) CancelOrder(c *gin.Context) { + subject, ok := middleware2.GetAuthSubjectFromContext(c) + if !ok { + response.Unauthorized(c, "User not authenticated") + return + } + + orderID, err := strconv.ParseInt(c.Param("id"), 10, 64) + if err != nil { + response.BadRequest(c, "Invalid order ID") + return + } + + msg, err := h.paymentService.CancelOrder(c.Request.Context(), orderID, subject.UserID) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, gin.H{"message": msg}) +} + +// RefundRequestBody is the request body for requesting a refund. +type RefundRequestBody struct { + Reason string `json:"reason"` +} + +// RequestRefund submits a refund request for a completed order. +// POST /api/v1/payment/orders/:id/refund-request +func (h *PaymentHandler) RequestRefund(c *gin.Context) { + subject, ok := middleware2.GetAuthSubjectFromContext(c) + if !ok { + response.Unauthorized(c, "User not authenticated") + return + } + + orderID, err := strconv.ParseInt(c.Param("id"), 10, 64) + if err != nil { + response.BadRequest(c, "Invalid order ID") + return + } + + var req RefundRequestBody + if err := c.ShouldBindJSON(&req); err != nil { + response.BadRequest(c, "Invalid request: "+err.Error()) + return + } + + if err := h.paymentService.RequestRefund(c.Request.Context(), orderID, subject.UserID, req.Reason); err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, gin.H{"message": "refund requested"}) +} + +// isMobile detects mobile user agents. +func isMobile(c *gin.Context) bool { + ua := strings.ToLower(c.GetHeader("User-Agent")) + return strings.Contains(ua, "mobile") || strings.Contains(ua, "android") || strings.Contains(ua, "iphone") +} diff --git a/backend/internal/handler/payment_webhook_handler.go b/backend/internal/handler/payment_webhook_handler.go new file mode 100644 index 0000000000..09650081b7 --- /dev/null +++ b/backend/internal/handler/payment_webhook_handler.go @@ -0,0 +1,103 @@ +package handler + +import ( + "io" + "log/slog" + "net/http" + + "github.com/Wei-Shaw/sub2api/internal/payment" + "github.com/Wei-Shaw/sub2api/internal/service" + + "github.com/gin-gonic/gin" +) + +// PaymentWebhookHandler handles payment provider webhook callbacks. +type PaymentWebhookHandler struct { + paymentService *service.PaymentService + registry *payment.Registry +} + +// NewPaymentWebhookHandler creates a new PaymentWebhookHandler. +func NewPaymentWebhookHandler(paymentService *service.PaymentService, registry *payment.Registry) *PaymentWebhookHandler { + return &PaymentWebhookHandler{ + paymentService: paymentService, + registry: registry, + } +} + +// EasyPayNotify handles EasyPay payment notifications. +// POST /api/v1/payment/webhook/easypay +func (h *PaymentWebhookHandler) EasyPayNotify(c *gin.Context) { + h.handleNotify(c, "easypay") +} + +// AlipayNotify handles Alipay payment notifications. +// POST /api/v1/payment/webhook/alipay +func (h *PaymentWebhookHandler) AlipayNotify(c *gin.Context) { + h.handleNotify(c, "alipay") +} + +// WxpayNotify handles WeChat Pay payment notifications. +// POST /api/v1/payment/webhook/wxpay +func (h *PaymentWebhookHandler) WxpayNotify(c *gin.Context) { + h.handleNotify(c, "wxpay") +} + +// StripeWebhook handles Stripe webhook events. +// POST /api/v1/payment/webhook/stripe +func (h *PaymentWebhookHandler) StripeWebhook(c *gin.Context) { + h.handleNotify(c, "stripe") +} + +// handleNotify is the shared logic for all provider webhook handlers. +func (h *PaymentWebhookHandler) handleNotify(c *gin.Context, providerKey string) { + body, err := io.ReadAll(io.LimitReader(c.Request.Body, 1<<20)) // 1MB limit + if err != nil { + slog.Error("[Payment Webhook] failed to read body", "provider", providerKey, "error", err) + c.String(http.StatusBadRequest, "failed to read body") + return + } + + provider, err := h.registry.GetProviderByKey(providerKey) + if err != nil { + slog.Warn("[Payment Webhook] provider not registered", "provider", providerKey, "error", err) + c.String(http.StatusOK, successResponse(providerKey)) + return + } + + headers := make(map[string]string) + for k := range c.Request.Header { + headers[k] = c.GetHeader(k) + } + + notification, err := provider.VerifyNotification(c.Request.Context(), string(body), headers) + if err != nil { + slog.Error("[Payment Webhook] verify failed", "provider", providerKey, "error", err) + c.String(http.StatusBadRequest, "verify failed") + return + } + + // nil notification means irrelevant event (e.g. Stripe non-payment event); return success. + if notification == nil { + c.String(http.StatusOK, successResponse(providerKey)) + return + } + + if err := h.paymentService.HandlePaymentNotification(c.Request.Context(), notification, providerKey); err != nil { + slog.Error("[Payment Webhook] handle notification failed", "provider", providerKey, "error", err) + c.String(http.StatusInternalServerError, "handle failed") + return + } + + c.String(http.StatusOK, successResponse(providerKey)) +} + +// successResponse returns the provider-specific success response string. +func successResponse(providerKey string) string { + switch providerKey { + case "stripe": + return "" + default: + return "success" + } +} diff --git a/backend/internal/handler/wire.go b/backend/internal/handler/wire.go index d9622594f2..4b54d41ad3 100644 --- a/backend/internal/handler/wire.go +++ b/backend/internal/handler/wire.go @@ -34,6 +34,7 @@ func ProvideAdminHandlers( apiKeyHandler *admin.AdminAPIKeyHandler, scheduledTestHandler *admin.ScheduledTestHandler, channelHandler *admin.ChannelHandler, + paymentHandler *admin.PaymentHandler, ) *AdminHandlers { return &AdminHandlers{ Dashboard: dashboardHandler, @@ -61,6 +62,7 @@ func ProvideAdminHandlers( APIKey: apiKeyHandler, ScheduledTest: scheduledTestHandler, Channel: channelHandler, + Payment: paymentHandler, } } @@ -88,22 +90,26 @@ func ProvideHandlers( openaiGatewayHandler *OpenAIGatewayHandler, settingHandler *SettingHandler, totpHandler *TotpHandler, + paymentHandler *PaymentHandler, + paymentWebhookHandler *PaymentWebhookHandler, _ *service.IdempotencyCoordinator, _ *service.IdempotencyCleanupService, ) *Handlers { return &Handlers{ - Auth: authHandler, - User: userHandler, - APIKey: apiKeyHandler, - Usage: usageHandler, - Redeem: redeemHandler, - Subscription: subscriptionHandler, - Announcement: announcementHandler, - Admin: adminHandlers, - Gateway: gatewayHandler, - OpenAIGateway: openaiGatewayHandler, - Setting: settingHandler, - Totp: totpHandler, + Auth: authHandler, + User: userHandler, + APIKey: apiKeyHandler, + Usage: usageHandler, + Redeem: redeemHandler, + Subscription: subscriptionHandler, + Announcement: announcementHandler, + Admin: adminHandlers, + Gateway: gatewayHandler, + OpenAIGateway: openaiGatewayHandler, + Setting: settingHandler, + Totp: totpHandler, + Payment: paymentHandler, + PaymentWebhook: paymentWebhookHandler, } } @@ -121,6 +127,8 @@ var ProviderSet = wire.NewSet( NewOpenAIGatewayHandler, NewTotpHandler, ProvideSettingHandler, + NewPaymentHandler, + NewPaymentWebhookHandler, // Admin handlers admin.NewDashboardHandler, @@ -148,6 +156,7 @@ var ProviderSet = wire.NewSet( admin.NewAdminAPIKeyHandler, admin.NewScheduledTestHandler, admin.NewChannelHandler, + admin.NewPaymentHandler, // AdminHandlers and Handlers constructors ProvideAdminHandlers, diff --git a/backend/internal/payment/crypto.go b/backend/internal/payment/crypto.go new file mode 100644 index 0000000000..e39e957f4d --- /dev/null +++ b/backend/internal/payment/crypto.go @@ -0,0 +1,98 @@ +package payment + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/base64" + "fmt" + "io" + "strings" +) + +// Encrypt encrypts plaintext using AES-256-GCM with the given 32-byte key. +// The output format is "iv:authTag:ciphertext" where each component is base64-encoded, +// matching the Node.js crypto.ts format for cross-compatibility. +func Encrypt(plaintext string, key []byte) (string, error) { + if len(key) != 32 { + return "", fmt.Errorf("encryption key must be 32 bytes, got %d", len(key)) + } + + block, err := aes.NewCipher(key) + if err != nil { + return "", fmt.Errorf("create AES cipher: %w", err) + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + return "", fmt.Errorf("create GCM: %w", err) + } + + nonce := make([]byte, gcm.NonceSize()) // 12 bytes for GCM + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + return "", fmt.Errorf("generate nonce: %w", err) + } + + // Seal appends the ciphertext + auth tag + sealed := gcm.Seal(nil, nonce, []byte(plaintext), nil) + + // Split sealed into ciphertext and auth tag (last 16 bytes) + tagSize := gcm.Overhead() + ciphertext := sealed[:len(sealed)-tagSize] + authTag := sealed[len(sealed)-tagSize:] + + // Format: iv:authTag:ciphertext (all base64) + return fmt.Sprintf("%s:%s:%s", + base64.StdEncoding.EncodeToString(nonce), + base64.StdEncoding.EncodeToString(authTag), + base64.StdEncoding.EncodeToString(ciphertext), + ), nil +} + +// Decrypt decrypts a ciphertext string produced by Encrypt. +// The input format is "iv:authTag:ciphertext" where each component is base64-encoded. +func Decrypt(ciphertext string, key []byte) (string, error) { + if len(key) != 32 { + return "", fmt.Errorf("encryption key must be 32 bytes, got %d", len(key)) + } + + parts := strings.SplitN(ciphertext, ":", 3) + if len(parts) != 3 { + return "", fmt.Errorf("invalid ciphertext format: expected iv:authTag:ciphertext") + } + + nonce, err := base64.StdEncoding.DecodeString(parts[0]) + if err != nil { + return "", fmt.Errorf("decode IV: %w", err) + } + + authTag, err := base64.StdEncoding.DecodeString(parts[1]) + if err != nil { + return "", fmt.Errorf("decode auth tag: %w", err) + } + + encrypted, err := base64.StdEncoding.DecodeString(parts[2]) + if err != nil { + return "", fmt.Errorf("decode ciphertext: %w", err) + } + + block, err := aes.NewCipher(key) + if err != nil { + return "", fmt.Errorf("create AES cipher: %w", err) + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + return "", fmt.Errorf("create GCM: %w", err) + } + + // Reconstruct the sealed data: ciphertext + authTag + sealed := append(encrypted, authTag...) + + plaintext, err := gcm.Open(nil, nonce, sealed, nil) + if err != nil { + return "", fmt.Errorf("decrypt: %w", err) + } + + return string(plaintext), nil +} diff --git a/backend/internal/payment/crypto_test.go b/backend/internal/payment/crypto_test.go new file mode 100644 index 0000000000..da8b6006e1 --- /dev/null +++ b/backend/internal/payment/crypto_test.go @@ -0,0 +1,183 @@ +package payment + +import ( + "crypto/rand" + "strings" + "testing" +) + +func makeKey(t *testing.T) []byte { + t.Helper() + key := make([]byte, 32) + if _, err := rand.Read(key); err != nil { + t.Fatalf("generate random key: %v", err) + } + return key +} + +func TestEncryptDecryptRoundTrip(t *testing.T) { + t.Parallel() + key := makeKey(t) + + plaintexts := []string{ + "hello world", + "short", + "a longer string with special chars: !@#$%^&*()", + `{"key":"value","num":42}`, + "你好世界 unicode test 🎉", + strings.Repeat("x", 10000), + } + + for _, pt := range plaintexts { + encrypted, err := Encrypt(pt, key) + if err != nil { + t.Fatalf("Encrypt(%q) error: %v", pt[:min(len(pt), 30)], err) + } + decrypted, err := Decrypt(encrypted, key) + if err != nil { + t.Fatalf("Decrypt error for plaintext %q: %v", pt[:min(len(pt), 30)], err) + } + if decrypted != pt { + t.Fatalf("round-trip failed: got %q, want %q", decrypted[:min(len(decrypted), 30)], pt[:min(len(pt), 30)]) + } + } +} + +func TestEncryptProducesDifferentCiphertexts(t *testing.T) { + t.Parallel() + key := makeKey(t) + + ct1, err := Encrypt("same plaintext", key) + if err != nil { + t.Fatalf("first Encrypt error: %v", err) + } + ct2, err := Encrypt("same plaintext", key) + if err != nil { + t.Fatalf("second Encrypt error: %v", err) + } + if ct1 == ct2 { + t.Fatal("two encryptions of the same plaintext should produce different ciphertexts (random nonce)") + } +} + +func TestDecryptWithWrongKeyFails(t *testing.T) { + t.Parallel() + key1 := makeKey(t) + key2 := makeKey(t) + + encrypted, err := Encrypt("secret data", key1) + if err != nil { + t.Fatalf("Encrypt error: %v", err) + } + + _, err = Decrypt(encrypted, key2) + if err == nil { + t.Fatal("Decrypt with wrong key should fail, but got nil error") + } +} + +func TestEncryptRejectsInvalidKeyLength(t *testing.T) { + t.Parallel() + badKeys := [][]byte{ + nil, + make([]byte, 0), + make([]byte, 16), + make([]byte, 31), + make([]byte, 33), + make([]byte, 64), + } + for _, key := range badKeys { + _, err := Encrypt("test", key) + if err == nil { + t.Fatalf("Encrypt should reject key of length %d", len(key)) + } + } +} + +func TestDecryptRejectsInvalidKeyLength(t *testing.T) { + t.Parallel() + badKeys := [][]byte{ + nil, + make([]byte, 16), + make([]byte, 33), + } + for _, key := range badKeys { + _, err := Decrypt("dummydata:dummydata:dummydata", key) + if err == nil { + t.Fatalf("Decrypt should reject key of length %d", len(key)) + } + } +} + +func TestEncryptEmptyPlaintext(t *testing.T) { + t.Parallel() + key := makeKey(t) + + encrypted, err := Encrypt("", key) + if err != nil { + t.Fatalf("Encrypt empty plaintext error: %v", err) + } + decrypted, err := Decrypt(encrypted, key) + if err != nil { + t.Fatalf("Decrypt empty plaintext error: %v", err) + } + if decrypted != "" { + t.Fatalf("expected empty string, got %q", decrypted) + } +} + +func TestEncryptDecryptUnicodeJSON(t *testing.T) { + t.Parallel() + key := makeKey(t) + + jsonContent := `{"name":"测试用户","email":"test@example.com","balance":100.50}` + encrypted, err := Encrypt(jsonContent, key) + if err != nil { + t.Fatalf("Encrypt JSON error: %v", err) + } + decrypted, err := Decrypt(encrypted, key) + if err != nil { + t.Fatalf("Decrypt JSON error: %v", err) + } + if decrypted != jsonContent { + t.Fatalf("JSON round-trip failed: got %q, want %q", decrypted, jsonContent) + } +} + +func TestDecryptInvalidFormat(t *testing.T) { + t.Parallel() + key := makeKey(t) + + invalidInputs := []string{ + "", + "nodelimiter", + "only:two", + "invalid:base64:!!!", + } + for _, input := range invalidInputs { + _, err := Decrypt(input, key) + if err == nil { + t.Fatalf("Decrypt(%q) should fail but got nil error", input) + } + } +} + +func TestCiphertextFormat(t *testing.T) { + t.Parallel() + key := makeKey(t) + + encrypted, err := Encrypt("test", key) + if err != nil { + t.Fatalf("Encrypt error: %v", err) + } + + parts := strings.SplitN(encrypted, ":", 3) + if len(parts) != 3 { + t.Fatalf("ciphertext should have format iv:authTag:ciphertext, got %d parts", len(parts)) + } + for i, part := range parts { + if part == "" { + t.Fatalf("ciphertext part %d is empty", i) + } + } +} diff --git a/backend/internal/payment/fee.go b/backend/internal/payment/fee.go new file mode 100644 index 0000000000..e2128e5efa --- /dev/null +++ b/backend/internal/payment/fee.go @@ -0,0 +1,19 @@ +package payment + +import ( + "github.com/shopspring/decimal" +) + +// CalculatePayAmount computes the total pay amount given a recharge amount and +// fee rate (percentage). Fee = amount * feeRate / 100, rounded UP (away from zero) +// to 2 decimal places. The returned string is formatted to exactly 2 decimal places. +// If feeRate <= 0, the amount is returned as-is (formatted to 2 decimal places). +func CalculatePayAmount(rechargeAmount float64, feeRate float64) string { + amount := decimal.NewFromFloat(rechargeAmount) + if feeRate <= 0 { + return amount.StringFixed(2) + } + rate := decimal.NewFromFloat(feeRate) + fee := amount.Mul(rate).Div(decimal.NewFromInt(100)).RoundUp(2) + return amount.Add(fee).StringFixed(2) +} diff --git a/backend/internal/payment/fee_test.go b/backend/internal/payment/fee_test.go new file mode 100644 index 0000000000..c58d1082a9 --- /dev/null +++ b/backend/internal/payment/fee_test.go @@ -0,0 +1,111 @@ +package payment + +import ( + "testing" +) + +func TestCalculatePayAmount(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + amount float64 + feeRate float64 + expected string + }{ + { + name: "zero fee rate returns same amount", + amount: 100.00, + feeRate: 0, + expected: "100.00", + }, + { + name: "negative fee rate returns same amount", + amount: 50.00, + feeRate: -5, + expected: "50.00", + }, + { + name: "1 percent fee rate", + amount: 100.00, + feeRate: 1, + expected: "101.00", + }, + { + name: "5 percent fee on 200", + amount: 200.00, + feeRate: 5, + expected: "210.00", + }, + { + name: "fee rounds UP to 2 decimal places", + amount: 100.00, + feeRate: 3, + expected: "103.00", + }, + { + name: "fee rounds UP small remainder", + amount: 10.00, + feeRate: 3.33, + expected: "10.34", // 10 * 3.33 / 100 = 0.333 -> round up -> 0.34 + }, + { + name: "very small amount", + amount: 0.01, + feeRate: 1, + expected: "0.02", // 0.01 * 1/100 = 0.0001 -> round up -> 0.01 -> total 0.02 + }, + { + name: "large amount", + amount: 99999.99, + feeRate: 10, + expected: "109999.99", // 99999.99 * 10/100 = 9999.999 -> round up -> 10000.00 -> total 109999.99 + }, + { + name: "100 percent fee rate doubles amount", + amount: 50.00, + feeRate: 100, + expected: "100.00", + }, + { + name: "precision 0.01 fee difference", + amount: 100.00, + feeRate: 1.01, + expected: "101.01", // 100 * 1.01/100 = 1.01 + }, + { + name: "precision 0.02 fee", + amount: 100.00, + feeRate: 1.02, + expected: "101.02", + }, + { + name: "zero amount with positive fee", + amount: 0, + feeRate: 5, + expected: "0.00", + }, + { + name: "fractional amount no fee", + amount: 19.99, + feeRate: 0, + expected: "19.99", + }, + { + name: "fractional fee that causes rounding up", + amount: 33.33, + feeRate: 7.77, + expected: "35.92", // 33.33 * 7.77 / 100 = 2.589741 -> round up -> 2.59 -> total 35.92 + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + got := CalculatePayAmount(tt.amount, tt.feeRate) + if got != tt.expected { + t.Fatalf("CalculatePayAmount(%v, %v) = %q, want %q", tt.amount, tt.feeRate, got, tt.expected) + } + }) + } +} diff --git a/backend/internal/payment/load_balancer.go b/backend/internal/payment/load_balancer.go new file mode 100644 index 0000000000..1a7371138c --- /dev/null +++ b/backend/internal/payment/load_balancer.go @@ -0,0 +1,144 @@ +package payment + +import ( + "context" + "encoding/json" + "fmt" + "strings" + "sync/atomic" + "time" + + dbent "github.com/Wei-Shaw/sub2api/ent" + "github.com/Wei-Shaw/sub2api/ent/paymentorder" + "github.com/Wei-Shaw/sub2api/ent/paymentproviderinstance" +) + +// Strategy represents a load balancing strategy for provider instance selection. +type Strategy string + +const ( + StrategyRoundRobin Strategy = "round_robin" + StrategyLeastAmount Strategy = "least_amount" +) + +// InstanceLimits holds per-channel limits for a provider instance (JSON). +type InstanceLimits map[string]struct { + DailyLimit float64 `json:"dailyLimit,omitempty"` + SingleMin float64 `json:"singleMin,omitempty"` + SingleMax float64 `json:"singleMax,omitempty"` +} + +// LoadBalancer selects a provider instance for a given payment type. +type LoadBalancer interface { + GetInstanceConfig(ctx context.Context, instanceID int64) (map[string]string, error) + SelectInstance(ctx context.Context, providerKey string, paymentType PaymentType) (*InstanceSelection, error) +} + +// DefaultLoadBalancer implements LoadBalancer using database queries. +type DefaultLoadBalancer struct { + db *dbent.Client + encryptionKey []byte + counter atomic.Uint64 +} + +// NewDefaultLoadBalancer creates a new load balancer. +func NewDefaultLoadBalancer(db *dbent.Client, encryptionKey []byte) *DefaultLoadBalancer { + return &DefaultLoadBalancer{db: db, encryptionKey: encryptionKey} +} + +// SelectInstance picks an enabled instance for the given provider key and payment type. +func (lb *DefaultLoadBalancer) SelectInstance(ctx context.Context, providerKey string, paymentType PaymentType) (*InstanceSelection, error) { + instances, err := lb.db.PaymentProviderInstance.Query(). + Where( + paymentproviderinstance.ProviderKey(providerKey), + paymentproviderinstance.Enabled(true), + ). + Order(dbent.Asc(paymentproviderinstance.FieldSortOrder)). + All(ctx) + if err != nil { + return nil, fmt.Errorf("query provider instances: %w", err) + } + + // Filter by supported types + var candidates []*dbent.PaymentProviderInstance + for _, inst := range instances { + if inst.SupportedTypes == "" || containsType(inst.SupportedTypes, paymentType) { + candidates = append(candidates, inst) + } + } + + if len(candidates) == 0 { + return nil, fmt.Errorf("no enabled instance for provider %s type %s", providerKey, paymentType) + } + + // Round-robin selection (default strategy) + idx := lb.counter.Add(1) % uint64(len(candidates)) + selected := candidates[idx] + + // Decrypt config + config, err := lb.decryptConfig(selected.Config) + if err != nil { + return nil, fmt.Errorf("decrypt instance %d config: %w", selected.ID, err) + } + + return &InstanceSelection{ + InstanceID: fmt.Sprintf("%d", selected.ID), + Config: config, + }, nil +} + +func (lb *DefaultLoadBalancer) decryptConfig(encrypted string) (map[string]string, error) { + plaintext, err := Decrypt(encrypted, lb.encryptionKey) + if err != nil { + return nil, err + } + var config map[string]string + if err := json.Unmarshal([]byte(plaintext), &config); err != nil { + return nil, fmt.Errorf("unmarshal config: %w", err) + } + return config, nil +} + +// GetInstanceDailyAmount returns the total completed order amount for an instance today. +func (lb *DefaultLoadBalancer) GetInstanceDailyAmount(ctx context.Context, instanceID string) (float64, error) { + now := time.Now() + todayStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) + + var result []struct { + Sum float64 `json:"sum"` + } + err := lb.db.PaymentOrder.Query(). + Where( + paymentorder.ProviderInstanceID(instanceID), + paymentorder.StatusIn("COMPLETED", "PAID", "RECHARGING"), + paymentorder.PaidAtGTE(todayStart), + ). + Aggregate(dbent.Sum(paymentorder.FieldPayAmount)). + Scan(ctx, &result) + if err != nil { + return 0, fmt.Errorf("query daily amount: %w", err) + } + if len(result) > 0 { + return result[0].Sum, nil + } + return 0, nil +} + +// containsType checks if a comma-separated list contains the given type. +func containsType(supportedTypes string, target PaymentType) bool { + for _, t := range strings.Split(supportedTypes, ",") { + if strings.TrimSpace(t) == target { + return true + } + } + return false +} + +// GetInstanceConfig decrypts and returns the configuration for a provider instance by ID. +func (lb *DefaultLoadBalancer) GetInstanceConfig(ctx context.Context, instanceID int64) (map[string]string, error) { + inst, err := lb.db.PaymentProviderInstance.Get(ctx, instanceID) + if err != nil { + return nil, fmt.Errorf("get instance %d: %w", instanceID, err) + } + return lb.decryptConfig(inst.Config) +} diff --git a/backend/internal/payment/load_balancer_test.go b/backend/internal/payment/load_balancer_test.go new file mode 100644 index 0000000000..78316cc4e6 --- /dev/null +++ b/backend/internal/payment/load_balancer_test.go @@ -0,0 +1,87 @@ +package payment + +import ( + "testing" +) + +func TestContainsType(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + supportedTypes string + target PaymentType + expected bool + }{ + { + name: "exact match single type", + supportedTypes: "alipay", + target: "alipay", + expected: true, + }, + { + name: "no match single type", + supportedTypes: "wxpay", + target: "alipay", + expected: false, + }, + { + name: "match in comma-separated list", + supportedTypes: "alipay,wxpay,stripe", + target: "wxpay", + expected: true, + }, + { + name: "first in comma-separated list", + supportedTypes: "alipay,wxpay", + target: "alipay", + expected: true, + }, + { + name: "last in comma-separated list", + supportedTypes: "alipay,wxpay,stripe", + target: "stripe", + expected: true, + }, + { + name: "no match in comma-separated list", + supportedTypes: "alipay,wxpay", + target: "stripe", + expected: false, + }, + { + name: "empty target", + supportedTypes: "alipay,wxpay", + target: "", + expected: false, + }, + { + name: "types with spaces are trimmed", + supportedTypes: " alipay , wxpay ", + target: "alipay", + expected: true, + }, + { + name: "partial match should not succeed", + supportedTypes: "alipay_direct", + target: "alipay", + expected: false, + }, + { + name: "empty supported types string matches nothing", + supportedTypes: "", + target: "alipay", + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + got := containsType(tt.supportedTypes, tt.target) + if got != tt.expected { + t.Fatalf("containsType(%q, %q) = %v, want %v", tt.supportedTypes, tt.target, got, tt.expected) + } + }) + } +} diff --git a/backend/internal/payment/provider/alipay.go b/backend/internal/payment/provider/alipay.go new file mode 100644 index 0000000000..55c119b232 --- /dev/null +++ b/backend/internal/payment/provider/alipay.go @@ -0,0 +1,261 @@ +package provider + +import ( + "context" + "fmt" + "net/url" + "strconv" + "strings" + "sync" + "time" + + "github.com/Wei-Shaw/sub2api/internal/payment" + "github.com/smartwalle/alipay/v3" +) + +// Alipay implements payment.Provider and payment.CancelableProvider using the smartwalle/alipay SDK. +type Alipay struct { + instanceID string + config map[string]string // appId, privateKey, publicKey (or alipayPublicKey), notifyUrl, returnUrl + + mu sync.Mutex + client *alipay.Client +} + +// NewAlipay creates a new Alipay provider instance. +func NewAlipay(instanceID string, config map[string]string) (*Alipay, error) { + required := []string{"appId", "privateKey"} + for _, k := range required { + if config[k] == "" { + return nil, fmt.Errorf("alipay config missing required key: %s", k) + } + } + return &Alipay{ + instanceID: instanceID, + config: config, + }, nil +} + +func (a *Alipay) getClient() (*alipay.Client, error) { + a.mu.Lock() + defer a.mu.Unlock() + if a.client != nil { + return a.client, nil + } + client, err := alipay.New(a.config["appId"], a.config["privateKey"], true) + if err != nil { + return nil, fmt.Errorf("alipay init client: %w", err) + } + pubKey := a.config["publicKey"] + if pubKey == "" { + pubKey = a.config["alipayPublicKey"] + } + if pubKey != "" { + if err := client.LoadAliPayPublicKey(pubKey); err != nil { + return nil, fmt.Errorf("alipay load public key: %w", err) + } + } + a.client = client + return a.client, nil +} + +func (a *Alipay) Name() string { return "Alipay" } +func (a *Alipay) ProviderKey() string { return "alipay" } +func (a *Alipay) SupportedTypes() []payment.PaymentType { + return []payment.PaymentType{payment.TypeAlipayDirect} +} + +// CreatePayment creates an Alipay payment page URL. +func (a *Alipay) CreatePayment(_ context.Context, req payment.CreatePaymentRequest) (*payment.CreatePaymentResponse, error) { + client, err := a.getClient() + if err != nil { + return nil, err + } + + notifyURL := a.config["notifyUrl"] + if req.NotifyURL != "" { + notifyURL = req.NotifyURL + } + returnURL := a.config["returnUrl"] + if req.ReturnURL != "" { + returnURL = req.ReturnURL + } + + if req.IsMobile { + return a.createWapPayment(client, req, notifyURL, returnURL) + } + return a.createPagePayment(client, req, notifyURL, returnURL) +} + +func (a *Alipay) createPagePayment(client *alipay.Client, req payment.CreatePaymentRequest, notifyURL, returnURL string) (*payment.CreatePaymentResponse, error) { + param := alipay.TradePagePay{} + param.OutTradeNo = req.OrderID + param.TotalAmount = req.Amount + param.Subject = req.Subject + param.ProductCode = "FAST_INSTANT_TRADE_PAY" + param.NotifyURL = notifyURL + param.ReturnURL = returnURL + + payURL, err := client.TradePagePay(param) + if err != nil { + return nil, fmt.Errorf("alipay TradePagePay: %w", err) + } + + return &payment.CreatePaymentResponse{ + TradeNo: req.OrderID, + PayURL: payURL.String(), + QRCode: payURL.String(), + }, nil +} + +func (a *Alipay) createWapPayment(client *alipay.Client, req payment.CreatePaymentRequest, notifyURL, returnURL string) (*payment.CreatePaymentResponse, error) { + param := alipay.TradeWapPay{} + param.OutTradeNo = req.OrderID + param.TotalAmount = req.Amount + param.Subject = req.Subject + param.ProductCode = "QUICK_WAP_WAY" + param.NotifyURL = notifyURL + param.ReturnURL = returnURL + + payURL, err := client.TradeWapPay(param) + if err != nil { + return nil, fmt.Errorf("alipay TradeWapPay: %w", err) + } + + return &payment.CreatePaymentResponse{ + TradeNo: req.OrderID, + PayURL: payURL.String(), + }, nil +} + +// QueryOrder queries the trade status via Alipay. +func (a *Alipay) QueryOrder(ctx context.Context, tradeNo string) (*payment.QueryOrderResponse, error) { + client, err := a.getClient() + if err != nil { + return nil, err + } + + result, err := client.TradeQuery(ctx, alipay.TradeQuery{OutTradeNo: tradeNo}) + if err != nil { + if isTradeNotExist(err) { + return &payment.QueryOrderResponse{ + TradeNo: tradeNo, + Status: "pending", + }, nil + } + return nil, fmt.Errorf("alipay TradeQuery: %w", err) + } + + status := "pending" + switch result.TradeStatus { + case alipay.TradeStatusSuccess, alipay.TradeStatusFinished: + status = "paid" + case alipay.TradeStatusClosed: + status = "failed" + } + + amount, _ := strconv.ParseFloat(result.TotalAmount, 64) + + return &payment.QueryOrderResponse{ + TradeNo: result.TradeNo, + Status: status, + Amount: amount, + PaidAt: result.SendPayDate, + }, nil +} + +// VerifyNotification decodes and verifies an Alipay async notification. +func (a *Alipay) VerifyNotification(ctx context.Context, rawBody string, _ map[string]string) (*payment.PaymentNotification, error) { + client, err := a.getClient() + if err != nil { + return nil, err + } + + values, err := url.ParseQuery(rawBody) + if err != nil { + return nil, fmt.Errorf("alipay parse notification: %w", err) + } + + notification, err := client.DecodeNotification(ctx, values) + if err != nil { + return nil, fmt.Errorf("alipay verify notification: %w", err) + } + + status := "failed" + if notification.TradeStatus == alipay.TradeStatusSuccess || notification.TradeStatus == alipay.TradeStatusFinished { + status = "success" + } + + amount, _ := strconv.ParseFloat(notification.TotalAmount, 64) + + return &payment.PaymentNotification{ + TradeNo: notification.TradeNo, + OrderID: notification.OutTradeNo, + Amount: amount, + Status: status, + RawData: rawBody, + }, nil +} + +// Refund requests a refund through Alipay. +func (a *Alipay) Refund(ctx context.Context, req payment.RefundRequest) (*payment.RefundResponse, error) { + client, err := a.getClient() + if err != nil { + return nil, err + } + + result, err := client.TradeRefund(ctx, alipay.TradeRefund{ + OutTradeNo: req.OrderID, + RefundAmount: req.Amount, + RefundReason: req.Reason, + OutRequestNo: fmt.Sprintf("%s-refund-%d", req.OrderID, time.Now().UnixNano()), + }) + if err != nil { + return nil, fmt.Errorf("alipay TradeRefund: %w", err) + } + + refundStatus := "pending" + if result.FundChange == "Y" { + refundStatus = "success" + } + + refundID := result.TradeNo + if refundID == "" { + refundID = req.OrderID + "-refund" + } + + return &payment.RefundResponse{ + RefundID: refundID, + Status: refundStatus, + }, nil +} + +// CancelPayment closes a pending trade on Alipay. +func (a *Alipay) CancelPayment(ctx context.Context, tradeNo string) error { + client, err := a.getClient() + if err != nil { + return err + } + + _, err = client.TradeClose(ctx, alipay.TradeClose{OutTradeNo: tradeNo}) + if err != nil { + if isTradeNotExist(err) { + return nil + } + return fmt.Errorf("alipay TradeClose: %w", err) + } + return nil +} + +func isTradeNotExist(err error) bool { + if err == nil { + return false + } + return strings.Contains(err.Error(), "ACQ.TRADE_NOT_EXIST") +} + +// Ensure interface compliance. +var ( + _ payment.Provider = (*Alipay)(nil) + _ payment.CancelableProvider = (*Alipay)(nil) +) diff --git a/backend/internal/payment/provider/easypay.go b/backend/internal/payment/provider/easypay.go new file mode 100644 index 0000000000..482712cde4 --- /dev/null +++ b/backend/internal/payment/provider/easypay.go @@ -0,0 +1,211 @@ +// Package provider contains concrete payment provider implementations. +package provider + +import ( + "context" + "crypto/hmac" + "crypto/md5" + "encoding/hex" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "sort" + "strings" + "time" + + "github.com/Wei-Shaw/sub2api/internal/payment" +) + +// EasyPay implements payment.Provider for the EasyPay aggregation platform. +type EasyPay struct { + instanceID string + config map[string]string + httpClient *http.Client +} + +// NewEasyPay creates a new EasyPay provider. +// config keys: pid, pkey, apiBase, notifyUrl, returnUrl, cid, cidAlipay, cidWxpay +func NewEasyPay(instanceID string, config map[string]string) (*EasyPay, error) { + for _, k := range []string{"pid", "pkey", "apiBase", "notifyUrl", "returnUrl"} { + if config[k] == "" { + return nil, fmt.Errorf("easypay config missing required key: %s", k) + } + } + return &EasyPay{ + instanceID: instanceID, + config: config, + httpClient: &http.Client{Timeout: 10 * time.Second}, + }, nil +} + +func (e *EasyPay) Name() string { return "EasyPay" } +func (e *EasyPay) ProviderKey() string { return "easypay" } +func (e *EasyPay) SupportedTypes() []payment.PaymentType { + return []payment.PaymentType{payment.TypeAlipay, payment.TypeWxpay} +} + +func (e *EasyPay) CreatePayment(ctx context.Context, req payment.CreatePaymentRequest) (*payment.CreatePaymentResponse, error) { + params := map[string]string{ + "pid": e.config["pid"], "type": req.PaymentType, + "out_trade_no": req.OrderID, "notify_url": req.NotifyURL, + "return_url": req.ReturnURL, "name": req.Subject, + "money": req.Amount, "clientip": req.ClientIP, + } + if cid := e.resolveCID(req.PaymentType); cid != "" { + params["cid"] = cid + } + if req.IsMobile { + params["device"] = "mobile" + } + params["sign"] = easyPaySign(params, e.config["pkey"]) + params["sign_type"] = "MD5" + + body, err := e.post(ctx, e.config["apiBase"]+"/mapi.php", params) + if err != nil { + return nil, fmt.Errorf("easypay create: %w", err) + } + var resp struct { + Code int `json:"code"` + Msg string `json:"msg"` + TradeNo string `json:"trade_no"` + PayURL string `json:"payurl"` + QRCode string `json:"qrcode"` + } + if err := json.Unmarshal(body, &resp); err != nil { + return nil, fmt.Errorf("easypay parse: %w", err) + } + if resp.Code != 1 { + return nil, fmt.Errorf("easypay error: %s", resp.Msg) + } + return &payment.CreatePaymentResponse{TradeNo: resp.TradeNo, PayURL: resp.PayURL, QRCode: resp.QRCode}, nil +} + +func (e *EasyPay) QueryOrder(ctx context.Context, tradeNo string) (*payment.QueryOrderResponse, error) { + params := map[string]string{ + "act": "order", "pid": e.config["pid"], + "key": e.config["pkey"], "out_trade_no": tradeNo, + } + body, err := e.post(ctx, e.config["apiBase"]+"/api.php", params) + if err != nil { + return nil, fmt.Errorf("easypay query: %w", err) + } + var resp struct { + Code int `json:"code"` + Msg string `json:"msg"` + Status int `json:"status"` + } + if err := json.Unmarshal(body, &resp); err != nil { + return nil, fmt.Errorf("easypay parse query: %w", err) + } + status := "pending" + if resp.Status == 1 { + status = "paid" + } + return &payment.QueryOrderResponse{TradeNo: tradeNo, Status: status}, nil +} + +func (e *EasyPay) VerifyNotification(_ context.Context, rawBody string, _ map[string]string) (*payment.PaymentNotification, error) { + values, err := url.ParseQuery(rawBody) + if err != nil { + return nil, fmt.Errorf("parse notify: %w", err) + } + params := make(map[string]string) + for k := range values { + params[k] = values.Get(k) + } + sign := params["sign"] + if sign == "" { + return nil, fmt.Errorf("missing sign") + } + if !easyPayVerifySign(params, e.config["pkey"], sign) { + return nil, fmt.Errorf("invalid signature") + } + status := "failed" + if params["trade_status"] == "TRADE_SUCCESS" { + status = "success" + } + return &payment.PaymentNotification{ + TradeNo: params["trade_no"], OrderID: params["out_trade_no"], + Status: status, RawData: rawBody, + }, nil +} + +func (e *EasyPay) Refund(ctx context.Context, req payment.RefundRequest) (*payment.RefundResponse, error) { + params := map[string]string{ + "pid": e.config["pid"], "key": e.config["pkey"], + "trade_no": req.TradeNo, "out_trade_no": req.OrderID, "money": req.Amount, + } + body, err := e.post(ctx, e.config["apiBase"]+"/api.php?act=refund", params) + if err != nil { + return nil, fmt.Errorf("easypay refund: %w", err) + } + var resp struct { + Code int `json:"code"` + Msg string `json:"msg"` + } + if err := json.Unmarshal(body, &resp); err != nil { + return nil, fmt.Errorf("easypay parse refund: %w", err) + } + if resp.Code != 1 { + return nil, fmt.Errorf("easypay refund failed: %s", resp.Msg) + } + return &payment.RefundResponse{RefundID: req.TradeNo, Status: "success"}, nil +} + +func (e *EasyPay) resolveCID(paymentType string) string { + if strings.HasPrefix(paymentType, "alipay") { + if v := e.config["cidAlipay"]; v != "" { + return v + } + return e.config["cid"] + } + if v := e.config["cidWxpay"]; v != "" { + return v + } + return e.config["cid"] +} + +func (e *EasyPay) post(ctx context.Context, endpoint string, params map[string]string) ([]byte, error) { + form := url.Values{} + for k, v := range params { + form.Set(k, v) + } + req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, strings.NewReader(form.Encode())) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + resp, err := e.httpClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + return io.ReadAll(resp.Body) +} + +func easyPaySign(params map[string]string, pkey string) string { + keys := make([]string, 0, len(params)) + for k, v := range params { + if k == "sign" || k == "sign_type" || v == "" { + continue + } + keys = append(keys, k) + } + sort.Strings(keys) + var buf strings.Builder + for i, k := range keys { + if i > 0 { + buf.WriteByte('&') + } + buf.WriteString(k + "=" + params[k]) + } + buf.WriteString(pkey) + hash := md5.Sum([]byte(buf.String())) + return hex.EncodeToString(hash[:]) +} + +func easyPayVerifySign(params map[string]string, pkey string, sign string) bool { + return hmac.Equal([]byte(easyPaySign(params, pkey)), []byte(sign)) +} diff --git a/backend/internal/payment/provider/easypay_sign_test.go b/backend/internal/payment/provider/easypay_sign_test.go new file mode 100644 index 0000000000..146a6fa1af --- /dev/null +++ b/backend/internal/payment/provider/easypay_sign_test.go @@ -0,0 +1,180 @@ +package provider + +import ( + "testing" +) + +func TestEasyPaySignConsistentOutput(t *testing.T) { + t.Parallel() + + params := map[string]string{ + "pid": "1001", + "type": "alipay", + "out_trade_no": "ORDER123", + "name": "Test Product", + "money": "10.00", + } + pkey := "test_secret_key" + + sign1 := easyPaySign(params, pkey) + sign2 := easyPaySign(params, pkey) + if sign1 != sign2 { + t.Fatalf("easyPaySign should be deterministic: %q != %q", sign1, sign2) + } + if len(sign1) != 32 { + t.Fatalf("MD5 hex should be 32 chars, got %d", len(sign1)) + } +} + +func TestEasyPaySignExcludesSignAndSignType(t *testing.T) { + t.Parallel() + + pkey := "my_key" + base := map[string]string{ + "pid": "1001", + "type": "alipay", + } + withSign := map[string]string{ + "pid": "1001", + "type": "alipay", + "sign": "should_be_ignored", + "sign_type": "MD5", + } + + signBase := easyPaySign(base, pkey) + signWithExtra := easyPaySign(withSign, pkey) + + if signBase != signWithExtra { + t.Fatalf("sign and sign_type should be excluded: base=%q, withExtra=%q", signBase, signWithExtra) + } +} + +func TestEasyPaySignExcludesEmptyValues(t *testing.T) { + t.Parallel() + + pkey := "key123" + base := map[string]string{ + "pid": "1001", + "type": "alipay", + } + withEmpty := map[string]string{ + "pid": "1001", + "type": "alipay", + "device": "", + "clientip": "", + } + + signBase := easyPaySign(base, pkey) + signWithEmpty := easyPaySign(withEmpty, pkey) + + if signBase != signWithEmpty { + t.Fatalf("empty values should be excluded: base=%q, withEmpty=%q", signBase, signWithEmpty) + } +} + +func TestEasyPayVerifySignValid(t *testing.T) { + t.Parallel() + + params := map[string]string{ + "pid": "1001", + "type": "alipay", + "out_trade_no": "ORDER456", + "money": "25.00", + } + pkey := "secret" + + sign := easyPaySign(params, pkey) + + // Add sign to params (as would come in a real callback) + params["sign"] = sign + params["sign_type"] = "MD5" + + if !easyPayVerifySign(params, pkey, sign) { + t.Fatal("easyPayVerifySign should return true for a valid signature") + } +} + +func TestEasyPayVerifySignTampered(t *testing.T) { + t.Parallel() + + params := map[string]string{ + "pid": "1001", + "type": "alipay", + "out_trade_no": "ORDER789", + "money": "50.00", + } + pkey := "secret" + + sign := easyPaySign(params, pkey) + + // Tamper with the amount + params["money"] = "99.99" + + if easyPayVerifySign(params, pkey, sign) { + t.Fatal("easyPayVerifySign should return false for tampered params") + } +} + +func TestEasyPayVerifySignWrongKey(t *testing.T) { + t.Parallel() + + params := map[string]string{ + "pid": "1001", + "type": "wxpay", + } + + sign := easyPaySign(params, "correct_key") + + if easyPayVerifySign(params, "wrong_key", sign) { + t.Fatal("easyPayVerifySign should return false with wrong key") + } +} + +func TestEasyPaySignEmptyParams(t *testing.T) { + t.Parallel() + + sign := easyPaySign(map[string]string{}, "key123") + if sign == "" { + t.Fatal("easyPaySign with empty params should still produce a hash") + } + if len(sign) != 32 { + t.Fatalf("MD5 hex should be 32 chars, got %d", len(sign)) + } +} + +func TestEasyPaySignSortOrder(t *testing.T) { + t.Parallel() + + pkey := "test_key" + params1 := map[string]string{ + "a": "1", + "b": "2", + "c": "3", + } + params2 := map[string]string{ + "c": "3", + "a": "1", + "b": "2", + } + + sign1 := easyPaySign(params1, pkey) + sign2 := easyPaySign(params2, pkey) + + if sign1 != sign2 { + t.Fatalf("easyPaySign should be order-independent: %q != %q", sign1, sign2) + } +} + +func TestEasyPayVerifySignWrongSignValue(t *testing.T) { + t.Parallel() + + params := map[string]string{ + "pid": "1001", + "type": "alipay", + } + pkey := "key" + + if easyPayVerifySign(params, pkey, "00000000000000000000000000000000") { + t.Fatal("easyPayVerifySign should return false for an incorrect sign value") + } +} diff --git a/backend/internal/payment/provider/factory.go b/backend/internal/payment/provider/factory.go new file mode 100644 index 0000000000..397ca064ae --- /dev/null +++ b/backend/internal/payment/provider/factory.go @@ -0,0 +1,23 @@ +package provider + +import ( + "fmt" + + "github.com/Wei-Shaw/sub2api/internal/payment" +) + +// CreateProvider creates a Provider from a provider key, instance ID and decrypted config. +func CreateProvider(providerKey string, instanceID string, config map[string]string) (payment.Provider, error) { + switch providerKey { + case "easypay": + return NewEasyPay(instanceID, config) + case "alipay": + return NewAlipay(instanceID, config) + case "wxpay": + return NewWxpay(instanceID, config) + case "stripe": + return NewStripe(instanceID, config) + default: + return nil, fmt.Errorf("unknown provider key: %s", providerKey) + } +} diff --git a/backend/internal/payment/provider/stripe.go b/backend/internal/payment/provider/stripe.go new file mode 100644 index 0000000000..850dfd88fa --- /dev/null +++ b/backend/internal/payment/provider/stripe.go @@ -0,0 +1,220 @@ +package provider + +import ( + "context" + "encoding/json" + "fmt" + "math" + "strconv" + "sync" + + "github.com/Wei-Shaw/sub2api/internal/payment" + stripe "github.com/stripe/stripe-go/v82" + "github.com/stripe/stripe-go/v82/client" + "github.com/stripe/stripe-go/v82/webhook" +) + +// Stripe implements the payment.CancelableProvider interface for Stripe payments. +type Stripe struct { + instanceID string + config map[string]string + + mu sync.Mutex + initialized bool + api *client.API +} + +// NewStripe creates a new Stripe provider instance. +func NewStripe(instanceID string, config map[string]string) (*Stripe, error) { + if config["secretKey"] == "" { + return nil, fmt.Errorf("stripe config missing required key: secretKey") + } + return &Stripe{ + instanceID: instanceID, + config: config, + }, nil +} + +func (s *Stripe) ensureInit() { + s.mu.Lock() + defer s.mu.Unlock() + if !s.initialized { + s.api = &client.API{} + s.api.Init(s.config["secretKey"], nil) + s.initialized = true + } +} + +// GetPublishableKey returns the publishable key for frontend use. +func (s *Stripe) GetPublishableKey() string { + return s.config["publishableKey"] +} + +func (s *Stripe) Name() string { return "Stripe" } +func (s *Stripe) ProviderKey() string { return "stripe" } +func (s *Stripe) SupportedTypes() []payment.PaymentType { + return []payment.PaymentType{payment.TypeStripe} +} + +// yuanToCents converts a CNY yuan string to cents (int64). +func yuanToCents(amountStr string) (int64, error) { + amount, err := strconv.ParseFloat(amountStr, 64) + if err != nil { + return 0, fmt.Errorf("invalid amount: %s", amountStr) + } + return int64(math.Round(amount * 100)), nil +} + +// CreatePayment creates a Stripe PaymentIntent. +func (s *Stripe) CreatePayment(ctx context.Context, req payment.CreatePaymentRequest) (*payment.CreatePaymentResponse, error) { + s.ensureInit() + + amountInCents, err := yuanToCents(req.Amount) + if err != nil { + return nil, fmt.Errorf("stripe create payment: %w", err) + } + + params := &stripe.PaymentIntentParams{ + Amount: stripe.Int64(amountInCents), + Currency: stripe.String("cny"), + AutomaticPaymentMethods: &stripe.PaymentIntentAutomaticPaymentMethodsParams{ + Enabled: stripe.Bool(true), + }, + Description: stripe.String(req.Subject), + Metadata: map[string]string{"orderId": req.OrderID}, + } + params.SetIdempotencyKey(fmt.Sprintf("pi-%s", req.OrderID)) + params.Context = ctx + + pi, err := s.api.PaymentIntents.New(params) + if err != nil { + return nil, fmt.Errorf("stripe create payment: %w", err) + } + + return &payment.CreatePaymentResponse{ + TradeNo: pi.ID, + ClientSecret: pi.ClientSecret, + }, nil +} + +// QueryOrder retrieves a PaymentIntent by ID. +func (s *Stripe) QueryOrder(ctx context.Context, tradeNo string) (*payment.QueryOrderResponse, error) { + s.ensureInit() + + params := &stripe.PaymentIntentParams{} + params.Context = ctx + + pi, err := s.api.PaymentIntents.Get(tradeNo, params) + if err != nil { + return nil, fmt.Errorf("stripe query order: %w", err) + } + + status := "pending" + switch pi.Status { + case stripe.PaymentIntentStatusSucceeded: + status = "paid" + case stripe.PaymentIntentStatusCanceled: + status = "failed" + } + + return &payment.QueryOrderResponse{ + TradeNo: pi.ID, + Status: status, + Amount: float64(pi.Amount) / 100, + }, nil +} + +// VerifyNotification verifies a Stripe webhook event. +func (s *Stripe) VerifyNotification(_ context.Context, rawBody string, headers map[string]string) (*payment.PaymentNotification, error) { + s.ensureInit() + + webhookSecret := s.config["webhookSecret"] + if webhookSecret == "" { + return nil, fmt.Errorf("stripe webhookSecret not configured") + } + + sig := headers["stripe-signature"] + if sig == "" { + return nil, fmt.Errorf("stripe notification missing stripe-signature header") + } + + event, err := webhook.ConstructEvent([]byte(rawBody), sig, webhookSecret) + if err != nil { + return nil, fmt.Errorf("stripe verify notification: %w", err) + } + + switch event.Type { + case "payment_intent.succeeded": + return parseStripePaymentIntent(&event, "success", rawBody) + case "payment_intent.payment_failed": + return parseStripePaymentIntent(&event, "failed", rawBody) + } + + return nil, nil +} + +func parseStripePaymentIntent(event *stripe.Event, status string, rawBody string) (*payment.PaymentNotification, error) { + var pi stripe.PaymentIntent + if err := json.Unmarshal(event.Data.Raw, &pi); err != nil { + return nil, fmt.Errorf("stripe parse payment_intent: %w", err) + } + return &payment.PaymentNotification{ + TradeNo: pi.ID, + OrderID: pi.Metadata["orderId"], + Amount: float64(pi.Amount) / 100, + Status: status, + RawData: rawBody, + }, nil +} + +// Refund creates a Stripe refund. +func (s *Stripe) Refund(ctx context.Context, req payment.RefundRequest) (*payment.RefundResponse, error) { + s.ensureInit() + + amountInCents, err := yuanToCents(req.Amount) + if err != nil { + return nil, fmt.Errorf("stripe refund: %w", err) + } + + params := &stripe.RefundParams{ + PaymentIntent: stripe.String(req.TradeNo), + Amount: stripe.Int64(amountInCents), + Reason: stripe.String(string(stripe.RefundReasonRequestedByCustomer)), + } + params.Context = ctx + + r, err := s.api.Refunds.New(params) + if err != nil { + return nil, fmt.Errorf("stripe refund: %w", err) + } + + refundStatus := "pending" + if r.Status == stripe.RefundStatusSucceeded { + refundStatus = "success" + } + + return &payment.RefundResponse{ + RefundID: r.ID, + Status: refundStatus, + }, nil +} + +// CancelPayment cancels a pending PaymentIntent. +func (s *Stripe) CancelPayment(ctx context.Context, tradeNo string) error { + s.ensureInit() + + params := &stripe.PaymentIntentCancelParams{} + params.Context = ctx + + _, err := s.api.PaymentIntents.Cancel(tradeNo, params) + if err != nil { + return fmt.Errorf("stripe cancel payment: %w", err) + } + return nil +} + +// Ensure interface compliance. +var ( + _ payment.Provider = (*Stripe)(nil) + _ payment.CancelableProvider = (*Stripe)(nil) +) diff --git a/backend/internal/payment/provider/wxpay.go b/backend/internal/payment/provider/wxpay.go new file mode 100644 index 0000000000..e1946b7c40 --- /dev/null +++ b/backend/internal/payment/provider/wxpay.go @@ -0,0 +1,312 @@ +package provider + +import ( + "bytes" + "context" + "fmt" + "io" + "math" + "net/http" + "strconv" + "strings" + "sync" + "time" + + "github.com/Wei-Shaw/sub2api/internal/payment" + "github.com/wechatpay-apiv3/wechatpay-go/core" + "github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers" + "github.com/wechatpay-apiv3/wechatpay-go/core/notify" + "github.com/wechatpay-apiv3/wechatpay-go/core/option" + "github.com/wechatpay-apiv3/wechatpay-go/services/payments" + "github.com/wechatpay-apiv3/wechatpay-go/services/payments/h5" + "github.com/wechatpay-apiv3/wechatpay-go/services/payments/native" + "github.com/wechatpay-apiv3/wechatpay-go/services/refunddomestic" + "github.com/wechatpay-apiv3/wechatpay-go/utils" +) + +type Wxpay struct { + instanceID string + config map[string]string + mu sync.Mutex + coreClient *core.Client + notifyHandler *notify.Handler +} + +func NewWxpay(instanceID string, config map[string]string) (*Wxpay, error) { + required := []string{"appId", "mchId", "privateKey", "apiV3Key", "publicKey", "publicKeyId"} + for _, k := range required { + if config[k] == "" { + return nil, fmt.Errorf("wxpay config missing required key: %s", k) + } + } + if len(config["apiV3Key"]) != 32 { + return nil, fmt.Errorf("wxpay apiV3Key must be exactly 32 bytes, got %d", len(config["apiV3Key"])) + } + return &Wxpay{instanceID: instanceID, config: config}, nil +} + +func (w *Wxpay) Name() string { return "Wxpay" } +func (w *Wxpay) ProviderKey() string { return "wxpay" } +func (w *Wxpay) SupportedTypes() []payment.PaymentType { + return []payment.PaymentType{payment.TypeWxpayDirect} +} + +func formatPEM(key, keyType string) string { + key = strings.TrimSpace(key) + if strings.HasPrefix(key, "-----BEGIN") { + return key + } + return fmt.Sprintf("-----BEGIN %s-----\n%s\n-----END %s-----", keyType, key, keyType) +} + +func (w *Wxpay) ensureClient() (*core.Client, error) { + w.mu.Lock() + defer w.mu.Unlock() + if w.coreClient != nil { + return w.coreClient, nil + } + privateKey, err := utils.LoadPrivateKey(formatPEM(w.config["privateKey"], "PRIVATE KEY")) + if err != nil { + return nil, fmt.Errorf("wxpay load private key: %w", err) + } + publicKey, err := utils.LoadPublicKey(formatPEM(w.config["publicKey"], "PUBLIC KEY")) + if err != nil { + return nil, fmt.Errorf("wxpay load public key: %w", err) + } + certSerial := w.config["certSerial"] + if certSerial == "" { + certSerial = w.config["publicKeyId"] + } + verifier := verifiers.NewSHA256WithRSAPubkeyVerifier(w.config["publicKeyId"], *publicKey) + client, err := core.NewClient(context.Background(), + option.WithMerchantCredential(w.config["mchId"], certSerial, privateKey), + option.WithVerifier(verifier)) + if err != nil { + return nil, fmt.Errorf("wxpay init client: %w", err) + } + handler, err := notify.NewRSANotifyHandler(w.config["apiV3Key"], verifier) + if err != nil { + return nil, fmt.Errorf("wxpay init notify handler: %w", err) + } + w.notifyHandler = handler + w.coreClient = client + return w.coreClient, nil +} + +func yuanToFen(s string) (int64, error) { + f, err := strconv.ParseFloat(s, 64) + if err != nil { + return 0, fmt.Errorf("invalid amount: %s", s) + } + return int64(math.Round(f * 100)), nil +} + +func (w *Wxpay) CreatePayment(ctx context.Context, req payment.CreatePaymentRequest) (*payment.CreatePaymentResponse, error) { + client, err := w.ensureClient() + if err != nil { + return nil, err + } + notifyURL := w.config["notifyUrl"] + if notifyURL == "" { + notifyURL = req.NotifyURL + } + if notifyURL == "" { + return nil, fmt.Errorf("wxpay notifyUrl is required") + } + totalFen, err := yuanToFen(req.Amount) + if err != nil { + return nil, fmt.Errorf("wxpay create payment: %w", err) + } + if req.IsMobile && req.ClientIP != "" { + resp, err := w.createH5Order(ctx, client, req, notifyURL, totalFen) + if err == nil { + return resp, nil + } + if !strings.Contains(err.Error(), "NO_AUTH") { + return nil, err + } + } + return w.createNativeOrder(ctx, client, req, notifyURL, totalFen) +} + +func (w *Wxpay) createNativeOrder(ctx context.Context, c *core.Client, req payment.CreatePaymentRequest, notifyURL string, totalFen int64) (*payment.CreatePaymentResponse, error) { + svc := native.NativeApiService{Client: c} + cur := "CNY" + resp, _, err := svc.Prepay(ctx, native.PrepayRequest{ + Appid: core.String(w.config["appId"]), Mchid: core.String(w.config["mchId"]), + Description: core.String(req.Subject), OutTradeNo: core.String(req.OrderID), + NotifyUrl: core.String(notifyURL), + Amount: &native.Amount{Total: core.Int64(totalFen), Currency: &cur}, + }) + if err != nil { + return nil, fmt.Errorf("wxpay native prepay: %w", err) + } + codeURL := "" + if resp.CodeUrl != nil { + codeURL = *resp.CodeUrl + } + return &payment.CreatePaymentResponse{TradeNo: req.OrderID, QRCode: codeURL}, nil +} + +func (w *Wxpay) createH5Order(ctx context.Context, c *core.Client, req payment.CreatePaymentRequest, notifyURL string, totalFen int64) (*payment.CreatePaymentResponse, error) { + svc := h5.H5ApiService{Client: c} + cur := "CNY" + tp := "Wap" + resp, _, err := svc.Prepay(ctx, h5.PrepayRequest{ + Appid: core.String(w.config["appId"]), Mchid: core.String(w.config["mchId"]), + Description: core.String(req.Subject), OutTradeNo: core.String(req.OrderID), + NotifyUrl: core.String(notifyURL), + Amount: &h5.Amount{Total: core.Int64(totalFen), Currency: &cur}, + SceneInfo: &h5.SceneInfo{PayerClientIp: core.String(req.ClientIP), H5Info: &h5.H5Info{Type: &tp}}, + }) + if err != nil { + return nil, fmt.Errorf("wxpay h5 prepay: %w", err) + } + h5URL := "" + if resp.H5Url != nil { + h5URL = *resp.H5Url + } + return &payment.CreatePaymentResponse{TradeNo: req.OrderID, PayURL: h5URL}, nil +} + +func wxSV(s *string) string { + if s == nil { + return "" + } + return *s +} + +func mapWxState(s string) string { + switch s { + case "SUCCESS": + return "paid" + case "REFUND": + return "refunded" + case "CLOSED", "PAYERROR": + return "failed" + default: + return "pending" + } +} + +func (w *Wxpay) QueryOrder(ctx context.Context, tradeNo string) (*payment.QueryOrderResponse, error) { + c, err := w.ensureClient() + if err != nil { + return nil, err + } + svc := native.NativeApiService{Client: c} + tx, _, err := svc.QueryOrderByOutTradeNo(ctx, native.QueryOrderByOutTradeNoRequest{ + OutTradeNo: core.String(tradeNo), Mchid: core.String(w.config["mchId"]), + }) + if err != nil { + return nil, fmt.Errorf("wxpay query order: %w", err) + } + var amt float64 + if tx.Amount != nil && tx.Amount.Total != nil { + amt = float64(*tx.Amount.Total) / 100 + } + id := tradeNo + if tx.TransactionId != nil { + id = *tx.TransactionId + } + pa := "" + if tx.SuccessTime != nil { + pa = *tx.SuccessTime + } + return &payment.QueryOrderResponse{TradeNo: id, Status: mapWxState(wxSV(tx.TradeState)), Amount: amt, PaidAt: pa}, nil +} + +func (w *Wxpay) VerifyNotification(ctx context.Context, rawBody string, headers map[string]string) (*payment.PaymentNotification, error) { + if _, err := w.ensureClient(); err != nil { + return nil, err + } + r, err := http.NewRequestWithContext(ctx, http.MethodPost, "/", io.NopCloser(bytes.NewBufferString(rawBody))) + if err != nil { + return nil, fmt.Errorf("wxpay construct request: %w", err) + } + for k, v := range headers { + r.Header.Set(k, v) + } + var tx payments.Transaction + nr, err := w.notifyHandler.ParseNotifyRequest(ctx, r, &tx) + if err != nil { + return nil, fmt.Errorf("wxpay verify notification: %w", err) + } + if nr.EventType != "TRANSACTION.SUCCESS" { + return nil, nil + } + var amt float64 + if tx.Amount != nil && tx.Amount.Total != nil { + amt = float64(*tx.Amount.Total) / 100 + } + st := "failed" + if wxSV(tx.TradeState) == "SUCCESS" { + st = "success" + } + return &payment.PaymentNotification{ + TradeNo: wxSV(tx.TransactionId), OrderID: wxSV(tx.OutTradeNo), + Amount: amt, Status: st, RawData: rawBody, + }, nil +} + +func (w *Wxpay) Refund(ctx context.Context, req payment.RefundRequest) (*payment.RefundResponse, error) { + c, err := w.ensureClient() + if err != nil { + return nil, err + } + rf, err := yuanToFen(req.Amount) + if err != nil { + return nil, fmt.Errorf("wxpay refund amount: %w", err) + } + svc := native.NativeApiService{Client: c} + tx, _, err := svc.QueryOrderByOutTradeNo(ctx, native.QueryOrderByOutTradeNoRequest{ + OutTradeNo: core.String(req.OrderID), Mchid: core.String(w.config["mchId"]), + }) + if err != nil { + return nil, fmt.Errorf("wxpay refund query order: %w", err) + } + var tf int64 + if tx.Amount != nil && tx.Amount.Total != nil { + tf = *tx.Amount.Total + } + rs := refunddomestic.RefundsApiService{Client: c} + cur := "CNY" + res, _, err := rs.Create(ctx, refunddomestic.CreateRequest{ + OutTradeNo: core.String(req.OrderID), + OutRefundNo: core.String(fmt.Sprintf("%s-refund-%d", req.OrderID, time.Now().UnixNano())), + Reason: core.String(req.Reason), + Amount: &refunddomestic.AmountReq{Refund: core.Int64(rf), Total: core.Int64(tf), Currency: &cur}, + }) + if err != nil { + return nil, fmt.Errorf("wxpay refund: %w", err) + } + rid := wxSV(res.RefundId) + if rid == "" { + rid = fmt.Sprintf("%s-refund", req.OrderID) + } + st := "pending" + if res.Status != nil && *res.Status == refunddomestic.STATUS_SUCCESS { + st = "success" + } + return &payment.RefundResponse{RefundID: rid, Status: st}, nil +} + +func (w *Wxpay) CancelPayment(ctx context.Context, tradeNo string) error { + c, err := w.ensureClient() + if err != nil { + return err + } + svc := native.NativeApiService{Client: c} + _, err = svc.CloseOrder(ctx, native.CloseOrderRequest{ + OutTradeNo: core.String(tradeNo), Mchid: core.String(w.config["mchId"]), + }) + if err != nil { + return fmt.Errorf("wxpay cancel payment: %w", err) + } + return nil +} + +var ( + _ payment.Provider = (*Wxpay)(nil) + _ payment.CancelableProvider = (*Wxpay)(nil) +) diff --git a/backend/internal/payment/registry.go b/backend/internal/payment/registry.go new file mode 100644 index 0000000000..77fb61907e --- /dev/null +++ b/backend/internal/payment/registry.go @@ -0,0 +1,88 @@ +package payment + +import ( + "sync" + + infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors" +) + +// Registry is a thread-safe registry mapping PaymentType to Provider. +type Registry struct { + mu sync.RWMutex + providers map[PaymentType]Provider +} + +// ErrProviderNotFound is returned when a requested payment provider is not registered. +var ErrProviderNotFound = infraerrors.NotFound("PROVIDER_NOT_FOUND", "payment provider not registered") + +// NewRegistry creates a new empty provider registry. +func NewRegistry() *Registry { + return &Registry{ + providers: make(map[PaymentType]Provider), + } +} + +// Register adds a provider for each of its supported payment types. +// If a type was previously registered, it is overwritten. +func (r *Registry) Register(p Provider) { + r.mu.Lock() + defer r.mu.Unlock() + for _, t := range p.SupportedTypes() { + r.providers[t] = p + } +} + +// GetProvider returns the provider registered for the given payment type. +func (r *Registry) GetProvider(t PaymentType) (Provider, error) { + r.mu.RLock() + defer r.mu.RUnlock() + p, ok := r.providers[t] + if !ok { + return nil, ErrProviderNotFound + } + return p, nil +} + +// GetProviderByKey returns the first provider whose ProviderKey matches the given key. +func (r *Registry) GetProviderByKey(key string) (Provider, error) { + r.mu.RLock() + defer r.mu.RUnlock() + seen := make(map[string]bool) + for _, p := range r.providers { + k := p.ProviderKey() + if k == key && !seen[k] { + return p, nil + } + seen[k] = true + } + return nil, ErrProviderNotFound +} + +// GetProviderKey returns the provider key for the given payment type, or empty string if not found. +func (r *Registry) GetProviderKey(t PaymentType) string { + r.mu.RLock() + defer r.mu.RUnlock() + p, ok := r.providers[t] + if !ok { + return "" + } + return p.ProviderKey() +} + +// SupportedTypes returns all currently registered payment types. +func (r *Registry) SupportedTypes() []PaymentType { + r.mu.RLock() + defer r.mu.RUnlock() + types := make([]PaymentType, 0, len(r.providers)) + for t := range r.providers { + types = append(types, t) + } + return types +} + +// Clear removes all registered providers. +func (r *Registry) Clear() { + r.mu.Lock() + defer r.mu.Unlock() + r.providers = make(map[PaymentType]Provider) +} diff --git a/backend/internal/payment/registry_test.go b/backend/internal/payment/registry_test.go new file mode 100644 index 0000000000..6acfeb6abf --- /dev/null +++ b/backend/internal/payment/registry_test.go @@ -0,0 +1,234 @@ +package payment + +import ( + "context" + "fmt" + "sync" + "testing" +) + +// mockProvider implements the Provider interface for testing. +type mockProvider struct { + name string + key string + supportedTypes []PaymentType +} + +func (m *mockProvider) Name() string { return m.name } +func (m *mockProvider) ProviderKey() string { return m.key } +func (m *mockProvider) SupportedTypes() []PaymentType { return m.supportedTypes } +func (m *mockProvider) CreatePayment(_ context.Context, _ CreatePaymentRequest) (*CreatePaymentResponse, error) { + return nil, nil +} +func (m *mockProvider) QueryOrder(_ context.Context, _ string) (*QueryOrderResponse, error) { + return nil, nil +} +func (m *mockProvider) VerifyNotification(_ context.Context, _ string, _ map[string]string) (*PaymentNotification, error) { + return nil, nil +} +func (m *mockProvider) Refund(_ context.Context, _ RefundRequest) (*RefundResponse, error) { + return nil, nil +} + +func TestRegistryRegisterAndGetProvider(t *testing.T) { + t.Parallel() + r := NewRegistry() + + p := &mockProvider{ + name: "TestPay", + key: "testpay", + supportedTypes: []PaymentType{TypeAlipay, TypeWxpay}, + } + r.Register(p) + + got, err := r.GetProvider(TypeAlipay) + if err != nil { + t.Fatalf("GetProvider(alipay) error: %v", err) + } + if got.ProviderKey() != "testpay" { + t.Fatalf("GetProvider(alipay) key = %q, want %q", got.ProviderKey(), "testpay") + } + + got2, err := r.GetProvider(TypeWxpay) + if err != nil { + t.Fatalf("GetProvider(wxpay) error: %v", err) + } + if got2.ProviderKey() != "testpay" { + t.Fatalf("GetProvider(wxpay) key = %q, want %q", got2.ProviderKey(), "testpay") + } +} + +func TestRegistryGetProviderNotFound(t *testing.T) { + t.Parallel() + r := NewRegistry() + + _, err := r.GetProvider("nonexistent") + if err == nil { + t.Fatal("GetProvider for unregistered type should return error") + } +} + +func TestRegistryGetProviderByKey(t *testing.T) { + t.Parallel() + r := NewRegistry() + + p := &mockProvider{ + name: "EasyPay", + key: "easypay", + supportedTypes: []PaymentType{TypeAlipay}, + } + r.Register(p) + + got, err := r.GetProviderByKey("easypay") + if err != nil { + t.Fatalf("GetProviderByKey error: %v", err) + } + if got.Name() != "EasyPay" { + t.Fatalf("GetProviderByKey name = %q, want %q", got.Name(), "EasyPay") + } +} + +func TestRegistryGetProviderByKeyNotFound(t *testing.T) { + t.Parallel() + r := NewRegistry() + + _, err := r.GetProviderByKey("nonexistent") + if err == nil { + t.Fatal("GetProviderByKey for unknown key should return error") + } +} + +func TestRegistryGetProviderKeyUnknownType(t *testing.T) { + t.Parallel() + r := NewRegistry() + + key := r.GetProviderKey("unknown_type") + if key != "" { + t.Fatalf("GetProviderKey for unknown type should return empty, got %q", key) + } +} + +func TestRegistryGetProviderKeyKnownType(t *testing.T) { + t.Parallel() + r := NewRegistry() + + p := &mockProvider{ + name: "Stripe", + key: "stripe", + supportedTypes: []PaymentType{TypeStripe}, + } + r.Register(p) + + key := r.GetProviderKey(TypeStripe) + if key != "stripe" { + t.Fatalf("GetProviderKey(stripe) = %q, want %q", key, "stripe") + } +} + +func TestRegistrySupportedTypes(t *testing.T) { + t.Parallel() + r := NewRegistry() + + p1 := &mockProvider{ + name: "EasyPay", + key: "easypay", + supportedTypes: []PaymentType{TypeAlipay, TypeWxpay}, + } + p2 := &mockProvider{ + name: "Stripe", + key: "stripe", + supportedTypes: []PaymentType{TypeStripe}, + } + r.Register(p1) + r.Register(p2) + + types := r.SupportedTypes() + if len(types) != 3 { + t.Fatalf("SupportedTypes() len = %d, want 3", len(types)) + } + + typeSet := make(map[PaymentType]bool) + for _, tp := range types { + typeSet[tp] = true + } + for _, expected := range []PaymentType{TypeAlipay, TypeWxpay, TypeStripe} { + if !typeSet[expected] { + t.Fatalf("SupportedTypes() missing %q", expected) + } + } +} + +func TestRegistrySupportedTypesEmpty(t *testing.T) { + t.Parallel() + r := NewRegistry() + + types := r.SupportedTypes() + if len(types) != 0 { + t.Fatalf("SupportedTypes() on empty registry should be empty, got %d", len(types)) + } +} + +func TestRegistryOverwriteExisting(t *testing.T) { + t.Parallel() + r := NewRegistry() + + p1 := &mockProvider{ + name: "OldPay", + key: "old", + supportedTypes: []PaymentType{TypeAlipay}, + } + p2 := &mockProvider{ + name: "NewPay", + key: "new", + supportedTypes: []PaymentType{TypeAlipay}, + } + r.Register(p1) + r.Register(p2) + + got, err := r.GetProvider(TypeAlipay) + if err != nil { + t.Fatalf("GetProvider error: %v", err) + } + if got.Name() != "NewPay" { + t.Fatalf("expected overwritten provider, got %q", got.Name()) + } +} + +func TestRegistryConcurrentAccess(t *testing.T) { + t.Parallel() + r := NewRegistry() + + const goroutines = 50 + var wg sync.WaitGroup + wg.Add(goroutines * 2) + + // Concurrent writers + for i := 0; i < goroutines; i++ { + go func(idx int) { + defer wg.Done() + p := &mockProvider{ + name: fmt.Sprintf("Provider-%d", idx), + key: fmt.Sprintf("key-%d", idx), + supportedTypes: []PaymentType{PaymentType(fmt.Sprintf("type-%d", idx))}, + } + r.Register(p) + }(i) + } + + // Concurrent readers + for i := 0; i < goroutines; i++ { + go func() { + defer wg.Done() + _ = r.SupportedTypes() + _, _ = r.GetProvider("some-type") + _ = r.GetProviderKey("some-type") + }() + } + + wg.Wait() + + types := r.SupportedTypes() + if len(types) != goroutines { + t.Fatalf("after concurrent registration, expected %d types, got %d", goroutines, len(types)) + } +} diff --git a/backend/internal/payment/types.go b/backend/internal/payment/types.go new file mode 100644 index 0000000000..40d44418a6 --- /dev/null +++ b/backend/internal/payment/types.go @@ -0,0 +1,115 @@ +// Package payment provides the core payment provider abstraction, +// registry, load balancing, and shared utilities for the payment subsystem. +package payment + +import "context" + +// PaymentType represents a supported payment method. +type PaymentType = string + +// Supported payment type constants. +const ( + TypeAlipay PaymentType = "alipay" + TypeWxpay PaymentType = "wxpay" + TypeAlipayDirect PaymentType = "alipay_direct" + TypeWxpayDirect PaymentType = "wxpay_direct" + TypeStripe PaymentType = "stripe" +) + +// GetBasePaymentType extracts the base payment method from a composite key. +// For example, "alipay_direct" -> "alipay". +func GetBasePaymentType(t string) string { + switch { + case len(t) >= 6 && t[:6] == "alipay": + return "alipay" + case len(t) >= 5 && t[:5] == "wxpay": + return "wxpay" + case len(t) >= 6 && t[:6] == "stripe": + return "stripe" + default: + return t + } +} + +// CreatePaymentRequest holds the parameters for creating a new payment. +type CreatePaymentRequest struct { + OrderID string // Internal order ID + Amount string // Pay amount in CNY (formatted to 2 decimal places) + PaymentType string // e.g. "alipay", "wxpay" + Subject string // Product description + NotifyURL string // Webhook callback URL + ReturnURL string // Browser redirect URL after payment + ClientIP string // Payer's IP address + IsMobile bool // Whether the request comes from a mobile device +} + +// CreatePaymentResponse is returned after successfully initiating a payment. +type CreatePaymentResponse struct { + TradeNo string // Third-party transaction ID + PayURL string // H5 payment URL (alipay/wxpay) + QRCode string // QR code content for scanning + ClientSecret string // Stripe PaymentIntent client secret +} + +// QueryOrderResponse describes the payment status from the upstream provider. +type QueryOrderResponse struct { + TradeNo string + Status string // "pending", "paid", "failed", "refunded" + Amount float64 // Amount in CNY + PaidAt string // RFC3339 timestamp or empty +} + +// PaymentNotification is the parsed result of a webhook/notify callback. +type PaymentNotification struct { + TradeNo string + OrderID string + Amount float64 + Status string // "success" or "failed" + RawData string // Raw notification body for audit +} + +// RefundRequest contains the parameters for requesting a refund. +type RefundRequest struct { + TradeNo string + OrderID string + Amount string // Refund amount formatted to 2 decimal places + Reason string +} + +// RefundResponse is returned after a refund request. +type RefundResponse struct { + RefundID string + Status string // "success", "pending", "failed" +} + +// InstanceSelection holds the selected provider instance and its decrypted config. +type InstanceSelection struct { + InstanceID string + Config map[string]string +} + +// Provider defines the interface that all payment providers must implement. +type Provider interface { + // Name returns a human-readable name for this provider. + Name() string + // ProviderKey returns the unique key identifying this provider type (e.g. "easypay"). + ProviderKey() string + // SupportedTypes returns the list of payment types this provider handles. + SupportedTypes() []PaymentType + // CreatePayment initiates a payment and returns the upstream response. + CreatePayment(ctx context.Context, req CreatePaymentRequest) (*CreatePaymentResponse, error) + // QueryOrder queries the payment status of the given trade number. + QueryOrder(ctx context.Context, tradeNo string) (*QueryOrderResponse, error) + // VerifyNotification parses and verifies a webhook callback. + // Returns nil for unrecognized or irrelevant events (caller should return 200). + VerifyNotification(ctx context.Context, rawBody string, headers map[string]string) (*PaymentNotification, error) + // Refund requests a refund from the upstream provider. + Refund(ctx context.Context, req RefundRequest) (*RefundResponse, error) +} + +// CancelableProvider extends Provider with the ability to cancel pending payments. +type CancelableProvider interface { + Provider + // CancelPayment cancels/expires a pending payment on the upstream platform. + CancelPayment(ctx context.Context, tradeNo string) error +} diff --git a/backend/internal/payment/wire.go b/backend/internal/payment/wire.go new file mode 100644 index 0000000000..f3dc0abf0d --- /dev/null +++ b/backend/internal/payment/wire.go @@ -0,0 +1,38 @@ +package payment + +import ( + "encoding/hex" + + dbent "github.com/Wei-Shaw/sub2api/ent" + "github.com/Wei-Shaw/sub2api/internal/config" + "github.com/google/wire" +) + +// EncryptionKey is a named type for the payment encryption key (AES-256, 32 bytes). +// Using a named type avoids Wire ambiguity with other []byte parameters. +type EncryptionKey []byte + +// ProvideEncryptionKey derives the payment encryption key from the TOTP encryption key in config. +func ProvideEncryptionKey(cfg *config.Config) EncryptionKey { + key, _ := hex.DecodeString(cfg.Totp.EncryptionKey) + return EncryptionKey(key) +} + +// ProvideRegistry creates an empty payment provider registry. +// Providers are registered at runtime after application startup. +func ProvideRegistry() *Registry { + return NewRegistry() +} + +// ProvideDefaultLoadBalancer creates a DefaultLoadBalancer backed by the ent client. +func ProvideDefaultLoadBalancer(client *dbent.Client, key EncryptionKey) *DefaultLoadBalancer { + return NewDefaultLoadBalancer(client, []byte(key)) +} + +// ProviderSet is the Wire provider set for the payment package. +var ProviderSet = wire.NewSet( + ProvideEncryptionKey, + ProvideRegistry, + ProvideDefaultLoadBalancer, + wire.Bind(new(LoadBalancer), new(*DefaultLoadBalancer)), +) diff --git a/backend/internal/repository/channel_repo.go b/backend/internal/repository/channel_repo.go index 1e2c2e4cf3..ab0032b46d 100644 --- a/backend/internal/repository/channel_repo.go +++ b/backend/internal/repository/channel_repo.go @@ -42,9 +42,9 @@ func (r *channelRepository) Create(ctx context.Context, channel *service.Channel return err } err = tx.QueryRowContext(ctx, - `INSERT INTO channels (name, description, status, model_mapping, billing_model_source, restrict_models) VALUES ($1, $2, $3, $4, $5, $6) + `INSERT INTO channels (name, description, status, model_mapping, billing_model_source, restrict_models, features) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id, created_at, updated_at`, - channel.Name, channel.Description, channel.Status, modelMappingJSON, channel.BillingModelSource, channel.RestrictModels, + channel.Name, channel.Description, channel.Status, modelMappingJSON, channel.BillingModelSource, channel.RestrictModels, channel.Features, ).Scan(&channel.ID, &channel.CreatedAt, &channel.UpdatedAt) if err != nil { if isUniqueViolation(err) { @@ -75,9 +75,9 @@ func (r *channelRepository) GetByID(ctx context.Context, id int64) (*service.Cha ch := &service.Channel{} var modelMappingJSON []byte err := r.db.QueryRowContext(ctx, - `SELECT id, name, description, status, model_mapping, billing_model_source, restrict_models, created_at, updated_at + `SELECT id, name, description, status, model_mapping, billing_model_source, restrict_models, features, created_at, updated_at FROM channels WHERE id = $1`, id, - ).Scan(&ch.ID, &ch.Name, &ch.Description, &ch.Status, &modelMappingJSON, &ch.BillingModelSource, &ch.RestrictModels, &ch.CreatedAt, &ch.UpdatedAt) + ).Scan(&ch.ID, &ch.Name, &ch.Description, &ch.Status, &modelMappingJSON, &ch.BillingModelSource, &ch.RestrictModels, &ch.Features, &ch.CreatedAt, &ch.UpdatedAt) if err == sql.ErrNoRows { return nil, service.ErrChannelNotFound } @@ -108,9 +108,9 @@ func (r *channelRepository) Update(ctx context.Context, channel *service.Channel return err } result, err := tx.ExecContext(ctx, - `UPDATE channels SET name = $1, description = $2, status = $3, model_mapping = $4, billing_model_source = $5, restrict_models = $6, updated_at = NOW() - WHERE id = $7`, - channel.Name, channel.Description, channel.Status, modelMappingJSON, channel.BillingModelSource, channel.RestrictModels, channel.ID, + `UPDATE channels SET name = $1, description = $2, status = $3, model_mapping = $4, billing_model_source = $5, restrict_models = $6, features = $7, updated_at = NOW() + WHERE id = $8`, + channel.Name, channel.Description, channel.Status, modelMappingJSON, channel.BillingModelSource, channel.RestrictModels, channel.Features, channel.ID, ) if err != nil { if isUniqueViolation(err) { @@ -204,7 +204,7 @@ func (r *channelRepository) List(ctx context.Context, params pagination.Paginati for rows.Next() { var ch service.Channel var modelMappingJSON []byte - if err := rows.Scan(&ch.ID, &ch.Name, &ch.Description, &ch.Status, &modelMappingJSON, &ch.BillingModelSource, &ch.RestrictModels, &ch.CreatedAt, &ch.UpdatedAt); err != nil { + if err := rows.Scan(&ch.ID, &ch.Name, &ch.Description, &ch.Status, &modelMappingJSON, &ch.BillingModelSource, &ch.RestrictModels, &ch.Features, &ch.CreatedAt, &ch.UpdatedAt); err != nil { return nil, nil, fmt.Errorf("scan channel: %w", err) } ch.ModelMapping = unmarshalModelMapping(modelMappingJSON) @@ -248,7 +248,7 @@ func (r *channelRepository) List(ctx context.Context, params pagination.Paginati func (r *channelRepository) ListAll(ctx context.Context) ([]service.Channel, error) { rows, err := r.db.QueryContext(ctx, - `SELECT id, name, description, status, model_mapping, billing_model_source, restrict_models, created_at, updated_at FROM channels ORDER BY id`, + `SELECT id, name, description, status, model_mapping, billing_model_source, restrict_models, features, created_at, updated_at FROM channels ORDER BY id`, ) if err != nil { return nil, fmt.Errorf("query all channels: %w", err) @@ -260,7 +260,7 @@ func (r *channelRepository) ListAll(ctx context.Context) ([]service.Channel, err for rows.Next() { var ch service.Channel var modelMappingJSON []byte - if err := rows.Scan(&ch.ID, &ch.Name, &ch.Description, &ch.Status, &modelMappingJSON, &ch.BillingModelSource, &ch.RestrictModels, &ch.CreatedAt, &ch.UpdatedAt); err != nil { + if err := rows.Scan(&ch.ID, &ch.Name, &ch.Description, &ch.Status, &modelMappingJSON, &ch.BillingModelSource, &ch.RestrictModels, &ch.Features, &ch.CreatedAt, &ch.UpdatedAt); err != nil { return nil, fmt.Errorf("scan channel: %w", err) } ch.ModelMapping = unmarshalModelMapping(modelMappingJSON) diff --git a/backend/internal/server/router.go b/backend/internal/server/router.go index d60a142c87..a507b6f831 100644 --- a/backend/internal/server/router.go +++ b/backend/internal/server/router.go @@ -111,4 +111,5 @@ func registerRoutes( routes.RegisterUserRoutes(v1, h, jwtAuth, settingService) routes.RegisterAdminRoutes(v1, h, adminAuth) routes.RegisterGatewayRoutes(r, h, apiKeyAuth, apiKeyService, subscriptionService, opsService, settingService, cfg) + routes.RegisterPaymentRoutes(v1, h.Payment, h.PaymentWebhook, h.Admin.Payment, jwtAuth, adminAuth, settingService) } diff --git a/backend/internal/server/routes/payment.go b/backend/internal/server/routes/payment.go new file mode 100644 index 0000000000..828b68f361 --- /dev/null +++ b/backend/internal/server/routes/payment.go @@ -0,0 +1,92 @@ +package routes + +import ( + "github.com/Wei-Shaw/sub2api/internal/handler" + "github.com/Wei-Shaw/sub2api/internal/handler/admin" + "github.com/Wei-Shaw/sub2api/internal/server/middleware" + "github.com/Wei-Shaw/sub2api/internal/service" + + "github.com/gin-gonic/gin" +) + +// RegisterPaymentRoutes registers all payment-related routes: +// user-facing endpoints, webhook endpoints, and admin endpoints. +func RegisterPaymentRoutes( + v1 *gin.RouterGroup, + paymentHandler *handler.PaymentHandler, + webhookHandler *handler.PaymentWebhookHandler, + adminPaymentHandler *admin.PaymentHandler, + jwtAuth middleware.JWTAuthMiddleware, + adminAuth middleware.AdminAuthMiddleware, + settingService *service.SettingService, +) { + // --- User-facing payment endpoints (authenticated) --- + authenticated := v1.Group("/payment") + authenticated.Use(gin.HandlerFunc(jwtAuth)) + authenticated.Use(middleware.BackendModeUserGuard(settingService)) + { + authenticated.GET("/config", paymentHandler.GetPaymentConfig) + authenticated.GET("/plans", paymentHandler.GetPlans) + authenticated.GET("/channels", paymentHandler.GetChannels) + authenticated.GET("/limits", paymentHandler.GetLimits) + + orders := authenticated.Group("/orders") + { + orders.POST("", paymentHandler.CreateOrder) + orders.GET("/my", paymentHandler.GetMyOrders) + orders.GET("/:id", paymentHandler.GetOrder) + orders.POST("/:id/cancel", paymentHandler.CancelOrder) + orders.POST("/:id/refund-request", paymentHandler.RequestRefund) + } + } + + // --- Webhook endpoints (no auth) --- + webhook := v1.Group("/payment/webhook") + { + webhook.POST("/easypay", webhookHandler.EasyPayNotify) + webhook.POST("/alipay", webhookHandler.AlipayNotify) + webhook.POST("/wxpay", webhookHandler.WxpayNotify) + webhook.POST("/stripe", webhookHandler.StripeWebhook) + } + + // --- Admin payment endpoints (admin auth) --- + adminGroup := v1.Group("/admin/payment") + adminGroup.Use(gin.HandlerFunc(adminAuth)) + { + // Dashboard + adminGroup.GET("/dashboard", adminPaymentHandler.GetDashboard) + + // Config + adminGroup.GET("/config", adminPaymentHandler.GetConfig) + adminGroup.PUT("/config", adminPaymentHandler.UpdateConfig) + + // Orders + adminOrders := adminGroup.Group("/orders") + { + adminOrders.GET("", adminPaymentHandler.ListOrders) + adminOrders.GET("/:id", adminPaymentHandler.GetOrderDetail) + adminOrders.POST("/:id/cancel", adminPaymentHandler.CancelOrder) + adminOrders.POST("/:id/retry", adminPaymentHandler.RetryFulfillment) + adminOrders.POST("/:id/refund", adminPaymentHandler.ProcessRefund) + } + + + // Subscription Plans + plans := adminGroup.Group("/plans") + { + plans.GET("", adminPaymentHandler.ListPlans) + plans.POST("", adminPaymentHandler.CreatePlan) + plans.PUT("/:id", adminPaymentHandler.UpdatePlan) + plans.DELETE("/:id", adminPaymentHandler.DeletePlan) + } + + // Provider Instances + providers := adminGroup.Group("/providers") + { + providers.GET("", adminPaymentHandler.ListProviders) + providers.POST("", adminPaymentHandler.CreateProvider) + providers.PUT("/:id", adminPaymentHandler.UpdateProvider) + providers.DELETE("/:id", adminPaymentHandler.DeleteProvider) + } + } +} diff --git a/backend/internal/service/channel.go b/backend/internal/service/channel.go index 1697ed6f86..eac8144470 100644 --- a/backend/internal/service/channel.go +++ b/backend/internal/service/channel.go @@ -39,6 +39,7 @@ type Channel struct { Status string BillingModelSource string // "requested", "upstream", or "channel_mapped" RestrictModels bool // 是否限制模型(仅允许定价列表中的模型) + Features string // 渠道特性描述(JSON 数组),用于支付页面展示 CreatedAt time.Time UpdatedAt time.Time diff --git a/backend/internal/service/channel_service.go b/backend/internal/service/channel_service.go index 79678c4b80..ab22ed1337 100644 --- a/backend/internal/service/channel_service.go +++ b/backend/internal/service/channel_service.go @@ -665,6 +665,7 @@ func (s *ChannelService) Create(ctx context.Context, input *CreateChannelInput) GroupIDs: input.GroupIDs, ModelPricing: input.ModelPricing, ModelMapping: input.ModelMapping, + Features: input.Features, } if channel.BillingModelSource == "" { channel.BillingModelSource = BillingModelSourceChannelMapped @@ -735,6 +736,9 @@ func (s *ChannelService) applyUpdateInput(ctx context.Context, channel *Channel, if input.RestrictModels != nil { channel.RestrictModels = *input.RestrictModels } + if input.Features != nil { + channel.Features = *input.Features + } if input.GroupIDs != nil { if err := s.checkGroupConflicts(ctx, channel.ID, *input.GroupIDs); err != nil { return err @@ -923,6 +927,7 @@ type CreateChannelInput struct { ModelMapping map[string]map[string]string // platform → {src→dst} BillingModelSource string RestrictModels bool + Features string } // UpdateChannelInput 更新渠道输入 @@ -935,4 +940,5 @@ type UpdateChannelInput struct { ModelMapping map[string]map[string]string // platform → {src→dst} BillingModelSource string RestrictModels *bool + Features *string } diff --git a/backend/internal/service/payment_config_service.go b/backend/internal/service/payment_config_service.go new file mode 100644 index 0000000000..d617563b49 --- /dev/null +++ b/backend/internal/service/payment_config_service.go @@ -0,0 +1,509 @@ +package service + +import ( + "context" + "log/slog" + "encoding/json" + "fmt" + "strconv" + "strings" + + dbent "github.com/Wei-Shaw/sub2api/ent" + "github.com/Wei-Shaw/sub2api/ent/paymentproviderinstance" + "github.com/Wei-Shaw/sub2api/ent/subscriptionplan" + "github.com/Wei-Shaw/sub2api/internal/payment" + infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors" +) + +const ( + SettingPaymentEnabled = "payment_enabled" + SettingMinRechargeAmount = "MIN_RECHARGE_AMOUNT" + SettingMaxRechargeAmount = "MAX_RECHARGE_AMOUNT" + SettingDailyRechargeLimit = "DAILY_RECHARGE_LIMIT" + SettingOrderTimeoutMinutes = "ORDER_TIMEOUT_MINUTES" + SettingMaxPendingOrders = "MAX_PENDING_ORDERS" + SettingEnabledPaymentTypes = "ENABLED_PAYMENT_TYPES" + SettingLoadBalanceStrategy = "LOAD_BALANCE_STRATEGY" + SettingBalancePayDisabled = "BALANCE_PAYMENT_DISABLED" + SettingProductNamePrefix = "PRODUCT_NAME_PREFIX" + SettingProductNameSuffix = "PRODUCT_NAME_SUFFIX" + SettingCancelRateLimitOn = "CANCEL_RATE_LIMIT_ENABLED" + SettingCancelRateLimitMax = "CANCEL_RATE_LIMIT_MAX" + SettingCancelWindowSize = "CANCEL_RATE_LIMIT_WINDOW" + SettingCancelWindowUnit = "CANCEL_RATE_LIMIT_UNIT" + SettingCancelWindowMode = "CANCEL_RATE_LIMIT_WINDOW_MODE" +) + +// PaymentConfig holds the payment system configuration. +type PaymentConfig struct { + Enabled bool `json:"enabled"` + MinAmount float64 `json:"min_amount"` + MaxAmount float64 `json:"max_amount"` + DailyLimit float64 `json:"daily_limit"` + OrderTimeoutMin int `json:"order_timeout_minutes"` + MaxPendingOrders int `json:"max_pending_orders"` + EnabledTypes []string `json:"enabled_payment_types"` + BalanceDisabled bool `json:"balance_disabled"` + LoadBalanceStrategy string `json:"load_balance_strategy"` + ProductNamePrefix string `json:"product_name_prefix"` + ProductNameSuffix string `json:"product_name_suffix"` +} + +// UpdatePaymentConfigRequest contains fields to update payment configuration. +type UpdatePaymentConfigRequest struct { + Enabled *bool `json:"enabled"` + MinAmount *float64 `json:"min_amount"` + MaxAmount *float64 `json:"max_amount"` + DailyLimit *float64 `json:"daily_limit"` + OrderTimeoutMin *int `json:"order_timeout_minutes"` + MaxPendingOrders *int `json:"max_pending_orders"` + EnabledTypes []string `json:"enabled_payment_types"` + BalanceDisabled *bool `json:"balance_disabled"` + LoadBalanceStrategy *string `json:"load_balance_strategy"` + ProductNamePrefix *string `json:"product_name_prefix"` + ProductNameSuffix *string `json:"product_name_suffix"` +} + +// MethodLimits holds per-payment-type limits. +type MethodLimits struct { + PaymentType string `json:"paymentType"` + FeeRate float64 `json:"feeRate"` + DailyLimit float64 `json:"daily_limit"` + SingleMin float64 `json:"singleMin"` + SingleMax float64 `json:"singleMax"` +} + +type CreateProviderInstanceRequest struct { + ProviderKey string `json:"providerKey"` + Name string `json:"name"` + Config map[string]string `json:"config"` + SupportedTypes string `json:"supportedTypes"` + Enabled bool `json:"enabled"` + SortOrder int `json:"sortOrder"` + Limits string `json:"limits"` + RefundEnabled bool `json:"refundEnabled"` +} + +type UpdateProviderInstanceRequest struct { + Name *string `json:"name"` + Config map[string]string `json:"config"` + SupportedTypes *string `json:"supportedTypes"` + Enabled *bool `json:"enabled"` + SortOrder *int `json:"sortOrder"` + Limits *string `json:"limits"` + RefundEnabled *bool `json:"refundEnabled"` +} +type CreatePlanRequest struct { + GroupID int64 `json:"groupId"` + Name string `json:"name"` + Description string `json:"description"` + Price float64 `json:"price"` + OriginalPrice *float64 `json:"originalPrice"` + ValidityDays int `json:"validityDays"` + ValidityUnit string `json:"validityUnit"` + Features string `json:"features"` + ProductName string `json:"productName"` + ForSale bool `json:"forSale"` + SortOrder int `json:"sortOrder"` +} + +type UpdatePlanRequest struct { + GroupID *int64 `json:"groupId"` + Name *string `json:"name"` + Description *string `json:"description"` + Price *float64 `json:"price"` + OriginalPrice *float64 `json:"originalPrice"` + ValidityDays *int `json:"validityDays"` + ValidityUnit *string `json:"validityUnit"` + Features *string `json:"features"` + ProductName *string `json:"productName"` + ForSale *bool `json:"forSale"` + SortOrder *int `json:"sortOrder"` +} + +// PaymentConfigService manages payment configuration and CRUD for +// provider instances, channels, and subscription plans. +type PaymentConfigService struct { + entClient *dbent.Client + settingRepo SettingRepository + encryptionKey []byte +} + +// NewPaymentConfigService creates a new PaymentConfigService. +func NewPaymentConfigService(entClient *dbent.Client, settingRepo SettingRepository, encryptionKey []byte) *PaymentConfigService { + return &PaymentConfigService{entClient: entClient, settingRepo: settingRepo, encryptionKey: encryptionKey} +} + +// IsPaymentEnabled returns whether the payment system is enabled. +func (s *PaymentConfigService) IsPaymentEnabled(ctx context.Context) bool { + val, err := s.settingRepo.GetValue(ctx, SettingPaymentEnabled) + if err != nil { + return false + } + return val == "true" +} + +// GetPaymentConfig returns the full payment configuration. +func (s *PaymentConfigService) GetPaymentConfig(ctx context.Context) (*PaymentConfig, error) { + keys := []string{ + SettingPaymentEnabled, SettingMinRechargeAmount, SettingMaxRechargeAmount, + SettingDailyRechargeLimit, SettingOrderTimeoutMinutes, SettingMaxPendingOrders, + SettingEnabledPaymentTypes, SettingBalancePayDisabled, SettingLoadBalanceStrategy, + SettingProductNamePrefix, SettingProductNameSuffix, + } + vals, err := s.settingRepo.GetMultiple(ctx, keys) + if err != nil { + return nil, fmt.Errorf("get payment config settings: %w", err) + } + return s.parsePaymentConfig(vals), nil +} + +func (s *PaymentConfigService) parsePaymentConfig(vals map[string]string) *PaymentConfig { + cfg := &PaymentConfig{ + Enabled: vals[SettingPaymentEnabled] == "true", + MinAmount: pcParseFloat(vals[SettingMinRechargeAmount], 1), + MaxAmount: pcParseFloat(vals[SettingMaxRechargeAmount], 99999999.99), + DailyLimit: pcParseFloat(vals[SettingDailyRechargeLimit], 0), + OrderTimeoutMin: pcParseInt(vals[SettingOrderTimeoutMinutes], 30), + MaxPendingOrders: pcParseInt(vals[SettingMaxPendingOrders], 3), + BalanceDisabled: vals[SettingBalancePayDisabled] == "true", + LoadBalanceStrategy: vals[SettingLoadBalanceStrategy], + ProductNamePrefix: vals[SettingProductNamePrefix], + ProductNameSuffix: vals[SettingProductNameSuffix], + } + if cfg.LoadBalanceStrategy == "" { + cfg.LoadBalanceStrategy = "round-robin" + } + if raw := vals[SettingEnabledPaymentTypes]; raw != "" { + for _, t := range strings.Split(raw, ",") { + t = strings.TrimSpace(t) + if t != "" { + cfg.EnabledTypes = append(cfg.EnabledTypes, t) + } + } + } + return cfg +} + +// UpdatePaymentConfig updates the payment configuration settings. +func (s *PaymentConfigService) UpdatePaymentConfig(ctx context.Context, req UpdatePaymentConfigRequest) error { + m := make(map[string]string) + if req.Enabled != nil { + m[SettingPaymentEnabled] = strconv.FormatBool(*req.Enabled) + } + if req.MinAmount != nil { + m[SettingMinRechargeAmount] = strconv.FormatFloat(*req.MinAmount, 'f', 2, 64) + } + if req.MaxAmount != nil { + m[SettingMaxRechargeAmount] = strconv.FormatFloat(*req.MaxAmount, 'f', 2, 64) + } + if req.DailyLimit != nil { + m[SettingDailyRechargeLimit] = strconv.FormatFloat(*req.DailyLimit, 'f', 2, 64) + } + if req.OrderTimeoutMin != nil { + m[SettingOrderTimeoutMinutes] = strconv.Itoa(*req.OrderTimeoutMin) + } + if req.MaxPendingOrders != nil { + m[SettingMaxPendingOrders] = strconv.Itoa(*req.MaxPendingOrders) + } + if req.EnabledTypes != nil { + m[SettingEnabledPaymentTypes] = strings.Join(req.EnabledTypes, ",") + } + if req.BalanceDisabled != nil { + m[SettingBalancePayDisabled] = strconv.FormatBool(*req.BalanceDisabled) + } + if req.LoadBalanceStrategy != nil { + m[SettingLoadBalanceStrategy] = *req.LoadBalanceStrategy + } + if req.ProductNamePrefix != nil { + m[SettingProductNamePrefix] = *req.ProductNamePrefix + } + if req.ProductNameSuffix != nil { + m[SettingProductNameSuffix] = *req.ProductNameSuffix + } + if len(m) == 0 { + return nil + } + return s.settingRepo.SetMultiple(ctx, m) +} + +// --- Provider Instance CRUD --- + +func (s *PaymentConfigService) ListProviderInstances(ctx context.Context) ([]*dbent.PaymentProviderInstance, error) { + return s.entClient.PaymentProviderInstance.Query().Order(paymentproviderinstance.BySortOrder()).All(ctx) +} + +func (s *PaymentConfigService) CreateProviderInstance(ctx context.Context, req CreateProviderInstanceRequest) (*dbent.PaymentProviderInstance, error) { + enc, err := s.encryptConfig(req.Config) + if err != nil { + return nil, err + } + return s.entClient.PaymentProviderInstance.Create(). + SetProviderKey(req.ProviderKey).SetName(req.Name).SetConfig(enc). + SetSupportedTypes(req.SupportedTypes).SetEnabled(req.Enabled). + SetSortOrder(req.SortOrder).SetLimits(req.Limits).SetRefundEnabled(req.RefundEnabled). + Save(ctx) +} + +func (s *PaymentConfigService) UpdateProviderInstance(ctx context.Context, id int64, req UpdateProviderInstanceRequest) (*dbent.PaymentProviderInstance, error) { + u := s.entClient.PaymentProviderInstance.UpdateOneID(id) + if req.Name != nil { + u.SetName(*req.Name) + } + if req.Config != nil { + enc, err := s.encryptConfig(req.Config) + if err != nil { + return nil, err + } + u.SetConfig(enc) + } + if req.SupportedTypes != nil { + u.SetSupportedTypes(*req.SupportedTypes) + } + if req.Enabled != nil { + u.SetEnabled(*req.Enabled) + } + if req.SortOrder != nil { + u.SetSortOrder(*req.SortOrder) + } + if req.Limits != nil { + u.SetLimits(*req.Limits) + } + if req.RefundEnabled != nil { + u.SetRefundEnabled(*req.RefundEnabled) + } + return u.Save(ctx) +} + +func (s *PaymentConfigService) DeleteProviderInstance(ctx context.Context, id int64) error { + return s.entClient.PaymentProviderInstance.DeleteOneID(id).Exec(ctx) +} + +func (s *PaymentConfigService) encryptConfig(cfg map[string]string) (string, error) { + data, err := json.Marshal(cfg) + if err != nil { + return "", fmt.Errorf("marshal config: %w", err) + } + enc, err := payment.Encrypt(string(data), s.encryptionKey) + if err != nil { + return "", fmt.Errorf("encrypt config: %w", err) + } + return enc, nil +} + +// --- Channel CRUD --- + + +// --- Plan CRUD --- + +func (s *PaymentConfigService) ListPlans(ctx context.Context) ([]*dbent.SubscriptionPlan, error) { + return s.entClient.SubscriptionPlan.Query().Order(subscriptionplan.BySortOrder()).All(ctx) +} + +func (s *PaymentConfigService) ListPlansForSale(ctx context.Context) ([]*dbent.SubscriptionPlan, error) { + return s.entClient.SubscriptionPlan.Query().Where(subscriptionplan.ForSaleEQ(true)).Order(subscriptionplan.BySortOrder()).All(ctx) +} + +func (s *PaymentConfigService) CreatePlan(ctx context.Context, req CreatePlanRequest) (*dbent.SubscriptionPlan, error) { + b := s.entClient.SubscriptionPlan.Create(). + SetGroupID(req.GroupID).SetName(req.Name).SetDescription(req.Description). + SetPrice(req.Price).SetValidityDays(req.ValidityDays).SetValidityUnit(req.ValidityUnit). + SetFeatures(req.Features).SetProductName(req.ProductName). + SetForSale(req.ForSale).SetSortOrder(req.SortOrder) + if req.OriginalPrice != nil { + b.SetOriginalPrice(*req.OriginalPrice) + } + return b.Save(ctx) +} + +func (s *PaymentConfigService) UpdatePlan(ctx context.Context, id int64, req UpdatePlanRequest) (*dbent.SubscriptionPlan, error) { + u := s.entClient.SubscriptionPlan.UpdateOneID(id) + if req.GroupID != nil { + u.SetGroupID(*req.GroupID) + } + if req.Name != nil { + u.SetName(*req.Name) + } + if req.Description != nil { + u.SetDescription(*req.Description) + } + if req.Price != nil { + u.SetPrice(*req.Price) + } + if req.OriginalPrice != nil { + u.SetOriginalPrice(*req.OriginalPrice) + } + if req.ValidityDays != nil { + u.SetValidityDays(*req.ValidityDays) + } + if req.ValidityUnit != nil { + u.SetValidityUnit(*req.ValidityUnit) + } + if req.Features != nil { + u.SetFeatures(*req.Features) + } + if req.ProductName != nil { + u.SetProductName(*req.ProductName) + } + if req.ForSale != nil { + u.SetForSale(*req.ForSale) + } + if req.SortOrder != nil { + u.SetSortOrder(*req.SortOrder) + } + return u.Save(ctx) +} + +func (s *PaymentConfigService) DeletePlan(ctx context.Context, id int64) error { + return s.entClient.SubscriptionPlan.DeleteOneID(id).Exec(ctx) +} + +// GetPlan returns a subscription plan by ID. +func (s *PaymentConfigService) GetPlan(ctx context.Context, id int64) (*dbent.SubscriptionPlan, error) { + plan, err := s.entClient.SubscriptionPlan.Get(ctx, id) + if err != nil { + return nil, infraerrors.NotFound("PLAN_NOT_FOUND", "subscription plan not found") + } + return plan, nil +} + +// GetMethodLimits returns per-payment-type limits from enabled provider instances. +func (s *PaymentConfigService) GetMethodLimits(ctx context.Context, types []string) ([]MethodLimits, error) { + instances, err := s.entClient.PaymentProviderInstance.Query(). + Where(paymentproviderinstance.EnabledEQ(true)).All(ctx) + if err != nil { + return nil, fmt.Errorf("query provider instances: %w", err) + } + result := make([]MethodLimits, 0, len(types)) + for _, pt := range types { + ml := MethodLimits{PaymentType: pt} + for _, inst := range instances { + if !pcInstanceSupportsType(inst, pt) { + continue + } + pcApplyInstanceLimits(inst, pt, &ml) + } + result = append(result, ml) + } + return result, nil +} + +func pcInstanceSupportsType(inst *dbent.PaymentProviderInstance, pt string) bool { + if inst.SupportedTypes == "" { + return true + } + for _, t := range strings.Split(inst.SupportedTypes, ",") { + if strings.TrimSpace(t) == pt { + return true + } + } + return false +} + +func pcApplyInstanceLimits(inst *dbent.PaymentProviderInstance, pt string, ml *MethodLimits) { + if inst.Limits == "" { + return + } + var limits payment.InstanceLimits + if err := json.Unmarshal([]byte(inst.Limits), &limits); err != nil { + return + } + cl, ok := limits[pt] + if !ok { + return + } + if cl.DailyLimit > 0 && (ml.DailyLimit == 0 || cl.DailyLimit < ml.DailyLimit) { + ml.DailyLimit = cl.DailyLimit + } + if cl.SingleMin > 0 && (ml.SingleMin == 0 || cl.SingleMin > ml.SingleMin) { + ml.SingleMin = cl.SingleMin + } + if cl.SingleMax > 0 && (ml.SingleMax == 0 || cl.SingleMax < ml.SingleMax) { + ml.SingleMax = cl.SingleMax + } +} + +func pcParseFloat(s string, defaultVal float64) float64 { + if s == "" { + return defaultVal + } + v, err := strconv.ParseFloat(s, 64) + if err != nil { + return defaultVal + } + return v +} + +func pcParseInt(s string, defaultVal int) int { + if s == "" { + return defaultVal + } + v, err := strconv.Atoi(s) + if err != nil { + return defaultVal + } + return v +} + +// MigrateLegacyPurchaseURL checks if the old purchase_subscription_url setting +// exists and is enabled, and if so, migrates it to a custom_menu_item entry. +// This is a one-time migration that runs at startup. +func (s *PaymentConfigService) MigrateLegacyPurchaseURL(ctx context.Context) error { + enabled, _ := s.settingRepo.GetValue(ctx, SettingKeyPurchaseSubscriptionEnabled) + if enabled != "true" { + return nil + } + url, _ := s.settingRepo.GetValue(ctx, SettingKeyPurchaseSubscriptionURL) + url = strings.TrimSpace(url) + if url == "" { + return nil + } + + // Read current custom_menu_items + raw, _ := s.settingRepo.GetValue(ctx, SettingKeyCustomMenuItems) + type menuItem struct { + ID string `json:"id"` + Label string `json:"label"` + IconSVG string `json:"icon_svg"` + URL string `json:"url"` + Visibility string `json:"visibility"` + SortOrder int `json:"sort_order"` + } + var items []menuItem + if raw != "" { + _ = json.Unmarshal([]byte(raw), &items) + } + + // Check if already migrated (same URL exists) + for _, item := range items { + if item.URL == url { + return nil + } + } + + // Append migrated item + items = append(items, menuItem{ + ID: "migrated_purchase_subscription", + Label: "Purchase Subscription", + IconSVG: "", + URL: url, + Visibility: "user", + SortOrder: 0, + }) + + data, err := json.Marshal(items) + if err != nil { + return fmt.Errorf("marshal custom_menu_items: %w", err) + } + + // Save updated menu items and clear old settings + if err := s.settingRepo.SetMultiple(ctx, map[string]string{ + SettingKeyCustomMenuItems: string(data), + SettingKeyPurchaseSubscriptionEnabled: "false", + }); err != nil { + return fmt.Errorf("save migrated settings: %w", err) + } + + slog.Info("[payment] Migrated legacy purchase_subscription_url to custom menu item", "url", url) + return nil +} diff --git a/backend/internal/service/payment_config_service_test.go b/backend/internal/service/payment_config_service_test.go new file mode 100644 index 0000000000..ffc5f24250 --- /dev/null +++ b/backend/internal/service/payment_config_service_test.go @@ -0,0 +1,183 @@ +package service + +import ( + "testing" +) + +func TestPcParseFloat(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + input string + defaultVal float64 + expected float64 + }{ + {"empty string returns default", "", 1.0, 1.0}, + {"valid float", "3.14", 0, 3.14}, + {"valid integer as float", "42", 0, 42.0}, + {"invalid string returns default", "notanumber", 9.99, 9.99}, + {"zero value", "0", 5.0, 0}, + {"negative value", "-10.5", 0, -10.5}, + {"very large value", "99999999.99", 0, 99999999.99}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + got := pcParseFloat(tt.input, tt.defaultVal) + if got != tt.expected { + t.Fatalf("pcParseFloat(%q, %v) = %v, want %v", tt.input, tt.defaultVal, got, tt.expected) + } + }) + } +} + +func TestPcParseInt(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + input string + defaultVal int + expected int + }{ + {"empty string returns default", "", 30, 30}, + {"valid int", "10", 0, 10}, + {"invalid string returns default", "abc", 5, 5}, + {"float string returns default", "3.14", 0, 0}, + {"zero value", "0", 99, 0}, + {"negative value", "-1", 0, -1}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + got := pcParseInt(tt.input, tt.defaultVal) + if got != tt.expected { + t.Fatalf("pcParseInt(%q, %v) = %v, want %v", tt.input, tt.defaultVal, got, tt.expected) + } + }) + } +} + +func TestParsePaymentConfig(t *testing.T) { + t.Parallel() + + svc := &PaymentConfigService{} + + t.Run("empty vals uses defaults", func(t *testing.T) { + t.Parallel() + cfg := svc.parsePaymentConfig(map[string]string{}) + if cfg.Enabled { + t.Fatal("expected Enabled=false by default") + } + if cfg.MinAmount != 1 { + t.Fatalf("expected MinAmount=1, got %v", cfg.MinAmount) + } + if cfg.MaxAmount != 99999999.99 { + t.Fatalf("expected MaxAmount=99999999.99, got %v", cfg.MaxAmount) + } + if cfg.OrderTimeoutMin != 30 { + t.Fatalf("expected OrderTimeoutMin=30, got %v", cfg.OrderTimeoutMin) + } + if cfg.MaxPendingOrders != 3 { + t.Fatalf("expected MaxPendingOrders=3, got %v", cfg.MaxPendingOrders) + } + if cfg.LoadBalanceStrategy != "round-robin" { + t.Fatalf("expected LoadBalanceStrategy=round-robin, got %q", cfg.LoadBalanceStrategy) + } + if len(cfg.EnabledTypes) != 0 { + t.Fatalf("expected empty EnabledTypes, got %v", cfg.EnabledTypes) + } + }) + + t.Run("all values populated", func(t *testing.T) { + t.Parallel() + vals := map[string]string{ + SettingPaymentEnabled: "true", + SettingMinRechargeAmount: "5.00", + SettingMaxRechargeAmount: "1000.00", + SettingDailyRechargeLimit: "5000.00", + SettingOrderTimeoutMinutes: "15", + SettingMaxPendingOrders: "5", + SettingEnabledPaymentTypes: "alipay,wxpay,stripe", + SettingBalancePayDisabled: "true", + SettingLoadBalanceStrategy: "least_amount", + SettingProductNamePrefix: "PRE", + SettingProductNameSuffix: "SUF", + } + cfg := svc.parsePaymentConfig(vals) + + if !cfg.Enabled { + t.Fatal("expected Enabled=true") + } + if cfg.MinAmount != 5 { + t.Fatalf("MinAmount = %v, want 5", cfg.MinAmount) + } + if cfg.MaxAmount != 1000 { + t.Fatalf("MaxAmount = %v, want 1000", cfg.MaxAmount) + } + if cfg.DailyLimit != 5000 { + t.Fatalf("DailyLimit = %v, want 5000", cfg.DailyLimit) + } + if cfg.OrderTimeoutMin != 15 { + t.Fatalf("OrderTimeoutMin = %v, want 15", cfg.OrderTimeoutMin) + } + if cfg.MaxPendingOrders != 5 { + t.Fatalf("MaxPendingOrders = %v, want 5", cfg.MaxPendingOrders) + } + if len(cfg.EnabledTypes) != 3 { + t.Fatalf("EnabledTypes len = %d, want 3", len(cfg.EnabledTypes)) + } + if cfg.EnabledTypes[0] != "alipay" || cfg.EnabledTypes[1] != "wxpay" || cfg.EnabledTypes[2] != "stripe" { + t.Fatalf("EnabledTypes = %v, want [alipay wxpay stripe]", cfg.EnabledTypes) + } + if !cfg.BalanceDisabled { + t.Fatal("expected BalanceDisabled=true") + } + if cfg.LoadBalanceStrategy != "least_amount" { + t.Fatalf("LoadBalanceStrategy = %q, want %q", cfg.LoadBalanceStrategy, "least_amount") + } + if cfg.ProductNamePrefix != "PRE" { + t.Fatalf("ProductNamePrefix = %q, want %q", cfg.ProductNamePrefix, "PRE") + } + if cfg.ProductNameSuffix != "SUF" { + t.Fatalf("ProductNameSuffix = %q, want %q", cfg.ProductNameSuffix, "SUF") + } + }) + + t.Run("enabled types with spaces are trimmed", func(t *testing.T) { + t.Parallel() + vals := map[string]string{ + SettingEnabledPaymentTypes: " alipay , wxpay ", + } + cfg := svc.parsePaymentConfig(vals) + if len(cfg.EnabledTypes) != 2 { + t.Fatalf("EnabledTypes len = %d, want 2", len(cfg.EnabledTypes)) + } + if cfg.EnabledTypes[0] != "alipay" || cfg.EnabledTypes[1] != "wxpay" { + t.Fatalf("EnabledTypes = %v, want [alipay wxpay]", cfg.EnabledTypes) + } + }) + + t.Run("empty enabled types string", func(t *testing.T) { + t.Parallel() + vals := map[string]string{ + SettingEnabledPaymentTypes: "", + } + cfg := svc.parsePaymentConfig(vals) + if len(cfg.EnabledTypes) != 0 { + t.Fatalf("expected empty EnabledTypes for empty string, got %v", cfg.EnabledTypes) + } + }) +} + +func TestGetBasePaymentType(t *testing.T) { + t.Parallel() + + // Import from the payment package is not needed since GetBasePaymentType + // is in a different package. This test covers parsePaymentConfig which + // is the core pure function in this service. + // Integration tests for DB-dependent methods would go in a separate file. +} diff --git a/backend/internal/service/payment_order_expiry_service.go b/backend/internal/service/payment_order_expiry_service.go new file mode 100644 index 0000000000..850d8f737d --- /dev/null +++ b/backend/internal/service/payment_order_expiry_service.go @@ -0,0 +1,71 @@ +package service + +import ( + "context" + "log/slog" + "sync" + "time" +) + +// PaymentOrderExpiryService periodically expires timed-out payment orders. +type PaymentOrderExpiryService struct { + paymentSvc *PaymentService + interval time.Duration + stopCh chan struct{} + stopOnce sync.Once + wg sync.WaitGroup +} + +func NewPaymentOrderExpiryService(paymentSvc *PaymentService, interval time.Duration) *PaymentOrderExpiryService { + return &PaymentOrderExpiryService{ + paymentSvc: paymentSvc, + interval: interval, + stopCh: make(chan struct{}), + } +} + +func (s *PaymentOrderExpiryService) Start() { + if s == nil || s.paymentSvc == nil || s.interval <= 0 { + return + } + s.wg.Add(1) + go func() { + defer s.wg.Done() + ticker := time.NewTicker(s.interval) + defer ticker.Stop() + + s.runOnce() + for { + select { + case <-ticker.C: + s.runOnce() + case <-s.stopCh: + return + } + } + }() +} + +func (s *PaymentOrderExpiryService) Stop() { + if s == nil { + return + } + s.stopOnce.Do(func() { + close(s.stopCh) + }) + s.wg.Wait() +} + +func (s *PaymentOrderExpiryService) runOnce() { + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + expired, err := s.paymentSvc.ExpireTimedOutOrders(ctx) + if err != nil { + slog.Error("[PaymentOrderExpiry] failed to expire orders", "error", err) + return + } + if expired > 0 { + slog.Info("[PaymentOrderExpiry] expired timed-out orders", "count", expired) + } +} diff --git a/backend/internal/service/payment_service.go b/backend/internal/service/payment_service.go new file mode 100644 index 0000000000..f4e2cfff65 --- /dev/null +++ b/backend/internal/service/payment_service.go @@ -0,0 +1,1136 @@ +package service + +import ( + "context" + "sync" + "encoding/json" + "fmt" + "log/slog" + "math" + "strconv" + "strings" + "time" + + dbent "github.com/Wei-Shaw/sub2api/ent" + "github.com/Wei-Shaw/sub2api/ent/paymentauditlog" + "github.com/Wei-Shaw/sub2api/ent/paymentorder" + "github.com/Wei-Shaw/sub2api/ent/paymentproviderinstance" + "github.com/Wei-Shaw/sub2api/internal/payment" + "github.com/Wei-Shaw/sub2api/internal/payment/provider" + infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors" +) + +const ( + OrderStatusPending = "PENDING" + OrderStatusPaid = "PAID" + OrderStatusRecharging = "RECHARGING" + OrderStatusCompleted = "COMPLETED" + OrderStatusExpired = "EXPIRED" + OrderStatusCancelled = "CANCELLED" + OrderStatusFailed = "FAILED" + OrderStatusRefundRequested = "REFUND_REQUESTED" + OrderStatusRefunding = "REFUNDING" + OrderStatusPartiallyRefunded = "PARTIALLY_REFUNDED" + OrderStatusRefunded = "REFUNDED" + OrderStatusRefundFailed = "REFUND_FAILED" +) + +const ( + defaultMaxPendingOrders = 3 + paymentGraceMinutes = 5 +) + +type CreateOrderRequest struct { + UserID int64 + Amount float64 + PaymentType string + ClientIP string + IsMobile bool + SrcHost string + SrcURL string + OrderType string + PlanID int64 +} + +type CreateOrderResponse struct { + OrderID int64 `json:"orderId"` + Amount float64 `json:"amount"` + PayAmount float64 `json:"payAmount"` + FeeRate float64 `json:"feeRate"` + Status string `json:"status"` + PaymentType string `json:"paymentType"` + PayURL string `json:"payUrl,omitempty"` + QRCode string `json:"qrCode,omitempty"` + ClientSecret string `json:"clientSecret,omitempty"` + ExpiresAt time.Time `json:"expiresAt"` +} + +type OrderListParams struct { + Page int + PageSize int + Status string + OrderType string + PaymentType string +} + +type RefundPlan struct { + OrderID int64 + Order *dbent.PaymentOrder + RefundAmount float64 + GatewayAmount float64 + Reason string + Force bool + DeductBalance bool + DeductionType string + BalanceToDeduct float64 + SubDaysToDeduct int +} + +type RefundResult struct { + Success bool `json:"success"` + Warning string `json:"warning,omitempty"` + RequireForce bool `json:"requireForce,omitempty"` + BalanceDeducted float64 `json:"balanceDeducted,omitempty"` + SubDaysDeducted int `json:"subscriptionDaysDeducted,omitempty"` +} + +type DashboardStats struct { + TodayAmount float64 `json:"today_amount"` + TotalAmount float64 `json:"total_amount"` + TodayCount int `json:"today_count"` + TotalCount int `json:"total_count"` + AvgAmount float64 `json:"avg_amount"` + PendingOrders int `json:"pending_orders"` + + DailySeries []DailyStats `json:"daily_series"` + PaymentMethods []PaymentMethodStat `json:"payment_methods"` + TopUsers []TopUserStat `json:"top_users"` +} + +type DailyStats struct { + Date string `json:"date"` + Amount float64 `json:"amount"` + Count int `json:"count"` +} + +type PaymentMethodStat struct { + Type string `json:"type"` + Amount float64 `json:"amount"` + Count int `json:"count"` +} + +type TopUserStat struct { + UserID int64 `json:"user_id"` + Email string `json:"email"` + Amount float64 `json:"amount"` +} + +type PaymentService struct { + providerMu sync.Mutex + providersLoaded bool + entClient *dbent.Client + registry *payment.Registry + loadBalancer payment.LoadBalancer + redeemService *RedeemService + subscriptionSvc *SubscriptionService + configService *PaymentConfigService + userRepo UserRepository + groupRepo GroupRepository +} + +func NewPaymentService(entClient *dbent.Client, registry *payment.Registry, loadBalancer payment.LoadBalancer, redeemService *RedeemService, subscriptionSvc *SubscriptionService, configService *PaymentConfigService, userRepo UserRepository, groupRepo GroupRepository) *PaymentService { + return &PaymentService{entClient: entClient, registry: registry, loadBalancer: loadBalancer, redeemService: redeemService, subscriptionSvc: subscriptionSvc, configService: configService, userRepo: userRepo, groupRepo: groupRepo} +} + +// Start performs one-time startup tasks such as legacy settings migration. +func (s *PaymentService) Start(ctx context.Context) { + if err := s.configService.MigrateLegacyPurchaseURL(ctx); err != nil { + slog.Error("[payment] legacy purchase URL migration failed", "error", err) + } +} + +func (s *PaymentService) CreateOrder(ctx context.Context, req CreateOrderRequest) (*CreateOrderResponse, error) { + if req.OrderType == "" { + req.OrderType = "balance" + } + cfg, err := s.configService.GetPaymentConfig(ctx) + if err != nil { + return nil, fmt.Errorf("get payment config: %w", err) + } + if !cfg.Enabled { + return nil, infraerrors.Forbidden("PAYMENT_DISABLED", "payment system is disabled") + } + plan, err := s.validateOrderInput(ctx, req, cfg) + if err != nil { + return nil, err + } + user, err := s.userRepo.GetByID(ctx, req.UserID) + if err != nil { + return nil, fmt.Errorf("get user: %w", err) + } + if user.Status != "active" { + return nil, infraerrors.Forbidden("USER_INACTIVE", "user account is disabled") + } + amount := req.Amount + if plan != nil { + amount = plan.Price + } + feeRate := s.getFeeRate(req.PaymentType) + payAmountStr := payment.CalculatePayAmount(amount, feeRate) + payAmount, _ := strconv.ParseFloat(payAmountStr, 64) + order, err := s.createOrderInTx(ctx, req, user, plan, cfg, amount, feeRate, payAmount) + if err != nil { + return nil, err + } + resp, err := s.invokeProvider(ctx, order, req, cfg, payAmountStr, payAmount, plan) + if err != nil { + _ = s.entClient.PaymentOrder.DeleteOneID(order.ID).Exec(ctx) + return nil, err + } + return resp, nil +} + +func (s *PaymentService) validateOrderInput(ctx context.Context, req CreateOrderRequest, cfg *PaymentConfig) (*dbent.SubscriptionPlan, error) { + if req.OrderType == "balance" && cfg.BalanceDisabled { + return nil, infraerrors.Forbidden("BALANCE_PAYMENT_DISABLED", "balance recharge has been disabled") + } + if req.OrderType == "subscription" { + return s.validateSubOrder(ctx, req) + } + if req.Amount < cfg.MinAmount || req.Amount > cfg.MaxAmount { + return nil, infraerrors.BadRequest("INVALID_AMOUNT", fmt.Sprintf("amount must be between %.2f and %.2f", cfg.MinAmount, cfg.MaxAmount)) + } + return nil, nil +} + +func (s *PaymentService) validateSubOrder(ctx context.Context, req CreateOrderRequest) (*dbent.SubscriptionPlan, error) { + if req.PlanID == 0 { + return nil, infraerrors.BadRequest("INVALID_INPUT", "subscription order requires a plan") + } + plan, err := s.configService.GetPlan(ctx, req.PlanID) + if err != nil || !plan.ForSale { + return nil, infraerrors.NotFound("PLAN_NOT_AVAILABLE", "plan not found or not for sale") + } + group, err := s.groupRepo.GetByID(ctx, plan.GroupID) + if err != nil || group.Status != "active" { + return nil, infraerrors.NotFound("GROUP_NOT_FOUND", "subscription group is no longer available") + } + if !group.IsSubscriptionType() { + return nil, infraerrors.BadRequest("GROUP_TYPE_MISMATCH", "group is not a subscription type") + } + return plan, nil +} + +func (s *PaymentService) createOrderInTx(ctx context.Context, req CreateOrderRequest, user *User, plan *dbent.SubscriptionPlan, cfg *PaymentConfig, amount, feeRate, payAmount float64) (*dbent.PaymentOrder, error) { + tx, err := s.entClient.Tx(ctx) + if err != nil { + return nil, fmt.Errorf("begin transaction: %w", err) + } + defer func() { _ = tx.Rollback() }() + if err := s.checkPendingLimit(ctx, tx, req.UserID, cfg.MaxPendingOrders); err != nil { + return nil, err + } + if err := s.checkDailyLimit(ctx, tx, req.UserID, amount, cfg.DailyLimit); err != nil { + return nil, err + } + tm := cfg.OrderTimeoutMin + if tm <= 0 { + tm = 30 + } + exp := time.Now().Add(time.Duration(tm) * time.Minute) + b := tx.PaymentOrder.Create().SetUserID(req.UserID).SetUserEmail(user.Email).SetUserName(user.Username).SetNillableUserNotes(psNilIfEmpty(user.Notes)).SetAmount(amount).SetPayAmount(payAmount).SetFeeRate(feeRate).SetRechargeCode("").SetPaymentType(req.PaymentType).SetPaymentTradeNo("").SetOrderType(req.OrderType).SetStatus(OrderStatusPending).SetExpiresAt(exp).SetClientIP(req.ClientIP).SetSrcHost(req.SrcHost) + if req.SrcURL != "" { + b.SetSrcURL(req.SrcURL) + } + if plan != nil { + b.SetPlanID(plan.ID).SetSubscriptionGroupID(plan.GroupID).SetSubscriptionDays(psComputeValidityDays(plan.ValidityDays, plan.ValidityUnit)) + } + order, err := b.Save(ctx) + if err != nil { + return nil, fmt.Errorf("create order: %w", err) + } + code := fmt.Sprintf("PAY-%d-%d", order.ID, time.Now().UnixNano()%100000) + order, err = tx.PaymentOrder.UpdateOneID(order.ID).SetRechargeCode(code).Save(ctx) + if err != nil { + return nil, fmt.Errorf("set recharge code: %w", err) + } + if err := tx.Commit(); err != nil { + return nil, fmt.Errorf("commit order transaction: %w", err) + } + return order, nil +} + +func (s *PaymentService) checkPendingLimit(ctx context.Context, tx *dbent.Tx, userID int64, max int) error { + if max <= 0 { + max = defaultMaxPendingOrders + } + c, err := tx.PaymentOrder.Query().Where(paymentorder.UserIDEQ(userID), paymentorder.StatusEQ(OrderStatusPending)).Count(ctx) + if err != nil { + return fmt.Errorf("count pending orders: %w", err) + } + if c >= max { + return infraerrors.TooManyRequests("TOO_MANY_PENDING", fmt.Sprintf("too many pending orders (max %d)", max)) + } + return nil +} + +func (s *PaymentService) checkDailyLimit(ctx context.Context, tx *dbent.Tx, userID int64, amount, limit float64) error { + if limit <= 0 { + return nil + } + ts := psStartOfDayUTC(time.Now()) + orders, err := tx.PaymentOrder.Query().Where(paymentorder.UserIDEQ(userID), paymentorder.StatusIn(OrderStatusPaid, OrderStatusRecharging, OrderStatusCompleted), paymentorder.PaidAtGTE(ts)).All(ctx) + if err != nil { + return fmt.Errorf("query daily usage: %w", err) + } + var used float64 + for _, o := range orders { + used += o.Amount + } + if used+amount > limit { + return infraerrors.TooManyRequests("DAILY_LIMIT_EXCEEDED", fmt.Sprintf("daily recharge limit reached, remaining: %.2f", math.Max(0, limit-used))) + } + return nil +} + +func (s *PaymentService) invokeProvider(ctx context.Context, order *dbent.PaymentOrder, req CreateOrderRequest, cfg *PaymentConfig, payAmountStr string, payAmount float64, plan *dbent.SubscriptionPlan) (*CreateOrderResponse, error) { + s.EnsureProviders(ctx) + provider, err := s.registry.GetProvider(req.PaymentType) + if err != nil { + return nil, infraerrors.ServiceUnavailable("PAYMENT_GATEWAY_ERROR", fmt.Sprintf("payment method (%s) is not configured", req.PaymentType)) + } + sel, err := s.loadBalancer.SelectInstance(ctx, provider.ProviderKey(), req.PaymentType) + if err != nil { + return nil, fmt.Errorf("select provider instance: %w", err) + } + if sel == nil { + return nil, infraerrors.TooManyRequests("NO_AVAILABLE_INSTANCE", "no available payment instance") + } + subject := s.buildPaymentSubject(plan, payAmountStr, cfg) + pr, err := provider.CreatePayment(ctx, payment.CreatePaymentRequest{OrderID: strconv.FormatInt(order.ID, 10), Amount: payAmountStr, PaymentType: req.PaymentType, Subject: subject, ClientIP: req.ClientIP, IsMobile: req.IsMobile}) + if err != nil { + return nil, infraerrors.ServiceUnavailable("PAYMENT_GATEWAY_ERROR", "payment method is temporarily unavailable") + } + _, err = s.entClient.PaymentOrder.UpdateOneID(order.ID).SetPaymentTradeNo(pr.TradeNo).SetNillablePayURL(psNilIfEmpty(pr.PayURL)).SetNillableQrCode(psNilIfEmpty(pr.QRCode)).SetNillableProviderInstanceID(psNilIfEmpty(sel.InstanceID)).Save(ctx) + if err != nil { + return nil, fmt.Errorf("update order with payment details: %w", err) + } + s.writeAuditLog(ctx, order.ID, "ORDER_CREATED", fmt.Sprintf("user:%d", req.UserID), map[string]any{"amount": req.Amount, "paymentType": req.PaymentType, "orderType": req.OrderType}) + return &CreateOrderResponse{OrderID: order.ID, Amount: order.Amount, PayAmount: payAmount, FeeRate: order.FeeRate, Status: OrderStatusPending, PaymentType: req.PaymentType, PayURL: pr.PayURL, QRCode: pr.QRCode, ClientSecret: pr.ClientSecret, ExpiresAt: order.ExpiresAt}, nil +} + +func (s *PaymentService) buildPaymentSubject(plan *dbent.SubscriptionPlan, payAmountStr string, cfg *PaymentConfig) string { + if plan != nil { + if plan.ProductName != "" { + return plan.ProductName + } + return "Sub2API Subscription " + plan.Name + } + pf := strings.TrimSpace(cfg.ProductNamePrefix) + sf := strings.TrimSpace(cfg.ProductNameSuffix) + if pf != "" || sf != "" { + return strings.TrimSpace(pf + " " + payAmountStr + " " + sf) + } + return "Sub2API " + payAmountStr + " CNY" +} + +func (s *PaymentService) GetOrder(ctx context.Context, orderID, userID int64) (*dbent.PaymentOrder, error) { + o, err := s.entClient.PaymentOrder.Get(ctx, orderID) + if err != nil { + return nil, infraerrors.NotFound("NOT_FOUND", "order not found") + } + if o.UserID != userID { + return nil, infraerrors.Forbidden("FORBIDDEN", "no permission for this order") + } + return o, nil +} + +func (s *PaymentService) GetOrderByID(ctx context.Context, orderID int64) (*dbent.PaymentOrder, error) { + o, err := s.entClient.PaymentOrder.Get(ctx, orderID) + if err != nil { + return nil, infraerrors.NotFound("NOT_FOUND", "order not found") + } + return o, nil +} + +func (s *PaymentService) GetUserOrders(ctx context.Context, userID int64, p OrderListParams) ([]*dbent.PaymentOrder, int, error) { + q := s.entClient.PaymentOrder.Query().Where(paymentorder.UserIDEQ(userID)) + if p.Status != "" { + q = q.Where(paymentorder.StatusEQ(p.Status)) + } + if p.OrderType != "" { + q = q.Where(paymentorder.OrderTypeEQ(p.OrderType)) + } + if p.PaymentType != "" { + q = q.Where(paymentorder.PaymentTypeEQ(p.PaymentType)) + } + total, err := q.Clone().Count(ctx) + if err != nil { + return nil, 0, fmt.Errorf("count user orders: %w", err) + } + ps := p.PageSize + if ps <= 0 { + ps = 20 + } + if ps > 100 { + ps = 100 + } + pg := p.Page + if pg < 1 { + pg = 1 + } + orders, err := q.Order(dbent.Desc(paymentorder.FieldCreatedAt)).Limit(ps).Offset((pg - 1) * ps).All(ctx) + if err != nil { + return nil, 0, fmt.Errorf("query user orders: %w", err) + } + return orders, total, nil +} + +func (s *PaymentService) CancelOrder(ctx context.Context, orderID, userID int64) (string, error) { + o, err := s.entClient.PaymentOrder.Get(ctx, orderID) + if err != nil { + return "", infraerrors.NotFound("NOT_FOUND", "order not found") + } + if o.UserID != userID { + return "", infraerrors.Forbidden("FORBIDDEN", "no permission for this order") + } + if o.Status != OrderStatusPending { + return "", infraerrors.BadRequest("INVALID_STATUS", "order cannot be cancelled in current status") + } + return s.cancelCore(ctx, o, OrderStatusCancelled, fmt.Sprintf("user:%d", userID), "user cancelled order") +} + +func (s *PaymentService) AdminCancelOrder(ctx context.Context, orderID int64) (string, error) { + o, err := s.entClient.PaymentOrder.Get(ctx, orderID) + if err != nil { + return "", infraerrors.NotFound("NOT_FOUND", "order not found") + } + if o.Status != OrderStatusPending { + return "", infraerrors.BadRequest("INVALID_STATUS", "order cannot be cancelled in current status") + } + return s.cancelCore(ctx, o, OrderStatusCancelled, "admin", "admin cancelled order") +} + +func (s *PaymentService) cancelCore(ctx context.Context, o *dbent.PaymentOrder, fs, op, ad string) (string, error) { + if o.PaymentTradeNo != "" && o.PaymentType != "" { + if s.checkPaid(ctx, o) == "already_paid" { + return "already_paid", nil + } + } + c, err := s.entClient.PaymentOrder.Update().Where(paymentorder.IDEQ(o.ID), paymentorder.StatusEQ(OrderStatusPending)).SetStatus(fs).Save(ctx) + if err != nil { + return "", fmt.Errorf("update order status: %w", err) + } + if c > 0 { + s.writeAuditLog(ctx, o.ID, "ORDER_CANCELLED", op, map[string]any{"detail": ad}) + } + return "cancelled", nil +} + +func (s *PaymentService) checkPaid(ctx context.Context, o *dbent.PaymentOrder) string { + s.EnsureProviders(ctx) + prov, err := s.registry.GetProvider(o.PaymentType) + if err != nil { + return "" + } + resp, err := prov.QueryOrder(ctx, o.PaymentTradeNo) + if err != nil { + slog.Warn("query upstream failed", "orderID", o.ID, "error", err) + return "" + } + if resp.Status == "paid" { + _ = s.HandlePaymentNotification(ctx, &payment.PaymentNotification{TradeNo: o.PaymentTradeNo, OrderID: strconv.FormatInt(o.ID, 10), Amount: resp.Amount, Status: "success"}, prov.ProviderKey()) + return "already_paid" + } + if cp, ok := prov.(payment.CancelableProvider); ok { + _ = cp.CancelPayment(ctx, o.PaymentTradeNo) + } + return "" +} + +func (s *PaymentService) HandlePaymentNotification(ctx context.Context, n *payment.PaymentNotification, pk string) error { + if n.Status != "success" { + return nil + } + oid, err := strconv.ParseInt(n.OrderID, 10, 64) + if err != nil { + return fmt.Errorf("invalid order ID: %s", n.OrderID) + } + return s.confirmPayment(ctx, oid, n.TradeNo, n.Amount, pk) +} + +func (s *PaymentService) confirmPayment(ctx context.Context, oid int64, tradeNo string, paid float64, pk string) error { + o, err := s.entClient.PaymentOrder.Get(ctx, oid) + if err != nil { + slog.Error("order not found", "orderID", oid) + return nil + } + if math.Abs(paid-o.PayAmount) > 0.01 { + s.writeAuditLog(ctx, o.ID, "PAYMENT_AMOUNT_MISMATCH", pk, map[string]any{"expected": o.PayAmount, "paid": paid, "tradeNo": tradeNo}) + return fmt.Errorf("amount mismatch: expected %.2f, got %.2f", o.PayAmount, paid) + } + return s.toPaid(ctx, o, tradeNo, paid, pk) +} + +func (s *PaymentService) toPaid(ctx context.Context, o *dbent.PaymentOrder, tradeNo string, paid float64, pk string) error { + now := time.Now() + grace := now.Add(-paymentGraceMinutes * time.Minute) + c, err := s.entClient.PaymentOrder.Update().Where(paymentorder.IDEQ(o.ID), paymentorder.Or(paymentorder.StatusEQ(OrderStatusPending), paymentorder.And(paymentorder.StatusEQ(OrderStatusExpired), paymentorder.UpdatedAtGTE(grace)))).SetStatus(OrderStatusPaid).SetPayAmount(paid).SetPaymentTradeNo(tradeNo).SetPaidAt(now).ClearFailedAt().ClearFailedReason().Save(ctx) + if err != nil { + return fmt.Errorf("update to PAID: %w", err) + } + if c == 0 { + return s.alreadyProcessed(ctx, o) + } + s.writeAuditLog(ctx, o.ID, "ORDER_PAID", pk, map[string]any{"tradeNo": tradeNo, "paidAmount": paid}) + return s.executeFulfillment(ctx, o.ID) +} + +func (s *PaymentService) alreadyProcessed(ctx context.Context, o *dbent.PaymentOrder) error { + cur, err := s.entClient.PaymentOrder.Get(ctx, o.ID) + if err != nil { + return nil + } + switch cur.Status { + case OrderStatusCompleted, OrderStatusRefunded: + return nil + case OrderStatusFailed: + return s.executeFulfillment(ctx, o.ID) + case OrderStatusPaid, OrderStatusRecharging: + return fmt.Errorf("order %d is being processed", o.ID) + default: + return nil + } +} + +func (s *PaymentService) executeFulfillment(ctx context.Context, oid int64) error { + o, err := s.entClient.PaymentOrder.Get(ctx, oid) + if err != nil { + return fmt.Errorf("get order: %w", err) + } + if o.OrderType == "subscription" { + return s.ExecuteSubscriptionFulfillment(ctx, oid) + } + return s.ExecuteBalanceFulfillment(ctx, oid) +} + +func (s *PaymentService) ExecuteBalanceFulfillment(ctx context.Context, oid int64) error { + o, err := s.entClient.PaymentOrder.Get(ctx, oid) + if err != nil { + return infraerrors.NotFound("NOT_FOUND", "order not found") + } + if o.Status == OrderStatusCompleted { + return nil + } + if psIsRefundStatus(o.Status) { + return infraerrors.BadRequest("INVALID_STATUS", "refund-related order cannot fulfill") + } + if o.Status != OrderStatusPaid && o.Status != OrderStatusFailed { + return infraerrors.BadRequest("INVALID_STATUS", "order cannot fulfill in status "+o.Status) + } + c, err := s.entClient.PaymentOrder.Update().Where(paymentorder.IDEQ(oid), paymentorder.StatusIn(OrderStatusPaid, OrderStatusFailed)).SetStatus(OrderStatusRecharging).Save(ctx) + if err != nil { + return fmt.Errorf("lock: %w", err) + } + if c == 0 { + return nil + } + if err := s.doBalance(ctx, o); err != nil { + s.markFailed(ctx, oid, err) + return err + } + return nil +} + +func (s *PaymentService) doBalance(ctx context.Context, o *dbent.PaymentOrder) error { + rc := &RedeemCode{Code: o.RechargeCode, Type: RedeemTypeBalance, Value: o.Amount, Status: StatusUnused} + if err := s.redeemService.CreateCode(ctx, rc); err != nil { + return fmt.Errorf("create redeem code: %w", err) + } + if _, err := s.redeemService.Redeem(ctx, o.UserID, o.RechargeCode); err != nil { + return fmt.Errorf("redeem balance: %w", err) + } + now := time.Now() + _, err := s.entClient.PaymentOrder.Update().Where(paymentorder.IDEQ(o.ID), paymentorder.StatusEQ(OrderStatusRecharging)).SetStatus(OrderStatusCompleted).SetCompletedAt(now).Save(ctx) + if err != nil { + return fmt.Errorf("mark completed: %w", err) + } + s.writeAuditLog(ctx, o.ID, "RECHARGE_SUCCESS", "system", map[string]any{"rechargeCode": o.RechargeCode, "amount": o.Amount}) + return nil +} + +func (s *PaymentService) ExecuteSubscriptionFulfillment(ctx context.Context, oid int64) error { + o, err := s.entClient.PaymentOrder.Get(ctx, oid) + if err != nil { + return infraerrors.NotFound("NOT_FOUND", "order not found") + } + if o.Status == OrderStatusCompleted { + return nil + } + if psIsRefundStatus(o.Status) { + return infraerrors.BadRequest("INVALID_STATUS", "refund-related order cannot fulfill") + } + if o.Status != OrderStatusPaid && o.Status != OrderStatusFailed { + return infraerrors.BadRequest("INVALID_STATUS", "order cannot fulfill in status "+o.Status) + } + if o.SubscriptionGroupID == nil || o.SubscriptionDays == nil { + return infraerrors.BadRequest("INVALID_STATUS", "missing subscription info") + } + c, err := s.entClient.PaymentOrder.Update().Where(paymentorder.IDEQ(oid), paymentorder.StatusIn(OrderStatusPaid, OrderStatusFailed)).SetStatus(OrderStatusRecharging).Save(ctx) + if err != nil { + return fmt.Errorf("lock: %w", err) + } + if c == 0 { + return nil + } + if err := s.doSub(ctx, o); err != nil { + s.markFailed(ctx, oid, err) + return err + } + return nil +} + +func (s *PaymentService) doSub(ctx context.Context, o *dbent.PaymentOrder) error { + gid := *o.SubscriptionGroupID + days := *o.SubscriptionDays + g, err := s.groupRepo.GetByID(ctx, gid) + if err != nil || g.Status != "active" { + return fmt.Errorf("group %d no longer exists or inactive", gid) + } + _, _, err = s.subscriptionSvc.AssignOrExtendSubscription(ctx, &AssignSubscriptionInput{UserID: o.UserID, GroupID: gid, ValidityDays: days, AssignedBy: 0, Notes: fmt.Sprintf("payment order %d", o.ID)}) + if err != nil { + return fmt.Errorf("assign subscription: %w", err) + } + now := time.Now() + _, err = s.entClient.PaymentOrder.Update().Where(paymentorder.IDEQ(o.ID), paymentorder.StatusEQ(OrderStatusRecharging)).SetStatus(OrderStatusCompleted).SetCompletedAt(now).Save(ctx) + if err != nil { + return fmt.Errorf("mark completed: %w", err) + } + s.writeAuditLog(ctx, o.ID, "SUBSCRIPTION_SUCCESS", "system", map[string]any{"groupId": gid, "days": days, "amount": o.Amount}) + return nil +} + +func (s *PaymentService) markFailed(ctx context.Context, oid int64, cause error) { + now := time.Now() + r := psErrMsg(cause) + _, e := s.entClient.PaymentOrder.UpdateOneID(oid).SetStatus(OrderStatusFailed).SetFailedAt(now).SetFailedReason(r).Save(ctx) + if e != nil { + slog.Error("mark FAILED", "orderID", oid, "error", e) + } + s.writeAuditLog(ctx, oid, "FULFILLMENT_FAILED", "system", map[string]any{"reason": r}) +} + +func (s *PaymentService) RetryFulfillment(ctx context.Context, oid int64) error { + o, err := s.entClient.PaymentOrder.Get(ctx, oid) + if err != nil { + return infraerrors.NotFound("NOT_FOUND", "order not found") + } + if o.PaidAt == nil { + return infraerrors.BadRequest("INVALID_STATUS", "order is not paid") + } + if psIsRefundStatus(o.Status) { + return infraerrors.BadRequest("INVALID_STATUS", "refund-related order cannot retry") + } + if o.Status == OrderStatusRecharging { + return infraerrors.Conflict("CONFLICT", "order is being processed") + } + if o.Status == OrderStatusCompleted { + return infraerrors.BadRequest("INVALID_STATUS", "order already completed") + } + if o.Status != OrderStatusFailed && o.Status != OrderStatusPaid { + return infraerrors.BadRequest("INVALID_STATUS", "only paid and failed orders can retry") + } + _, err = s.entClient.PaymentOrder.Update().Where(paymentorder.IDEQ(oid), paymentorder.StatusIn(OrderStatusFailed, OrderStatusPaid)).SetStatus(OrderStatusPaid).ClearFailedAt().ClearFailedReason().Save(ctx) + if err != nil { + return fmt.Errorf("reset for retry: %w", err) + } + s.writeAuditLog(ctx, oid, "RECHARGE_RETRY", "admin", map[string]any{"detail": "admin manual retry"}) + return s.executeFulfillment(ctx, oid) +} + +func (s *PaymentService) RequestRefund(ctx context.Context, oid, uid int64, reason string) error { + o, err := s.entClient.PaymentOrder.Get(ctx, oid) + if err != nil { + return infraerrors.NotFound("NOT_FOUND", "order not found") + } + if o.UserID != uid { + return infraerrors.Forbidden("FORBIDDEN", "no permission") + } + if o.OrderType != "balance" { + return infraerrors.BadRequest("INVALID_ORDER_TYPE", "only balance orders can request refund") + } + if o.Status != OrderStatusCompleted { + return infraerrors.BadRequest("INVALID_STATUS", "only completed orders can request refund") + } + u, err := s.userRepo.GetByID(ctx, o.UserID) + if err != nil { + return fmt.Errorf("get user: %w", err) + } + if u.Balance < o.Amount { + return infraerrors.BadRequest("BALANCE_NOT_ENOUGH", "refund amount exceeds balance") + } + nr := strings.TrimSpace(reason) + now := time.Now() + by := fmt.Sprintf("%d", uid) + c, err := s.entClient.PaymentOrder.Update().Where(paymentorder.IDEQ(oid), paymentorder.UserIDEQ(uid), paymentorder.StatusEQ(OrderStatusCompleted), paymentorder.OrderTypeEQ("balance")).SetStatus(OrderStatusRefundRequested).SetRefundRequestedAt(now).SetRefundRequestReason(nr).SetRefundRequestedBy(by).SetRefundAmount(o.Amount).Save(ctx) + if err != nil { + return fmt.Errorf("update: %w", err) + } + if c == 0 { + return infraerrors.Conflict("CONFLICT", "order status changed") + } + s.writeAuditLog(ctx, oid, "REFUND_REQUESTED", fmt.Sprintf("user:%d", uid), map[string]any{"amount": o.Amount, "reason": nr}) + return nil +} + +func (s *PaymentService) PrepareRefund(ctx context.Context, oid int64, amt float64, reason string, force, deduct bool) (*RefundPlan, *RefundResult, error) { + o, err := s.entClient.PaymentOrder.Get(ctx, oid) + if err != nil { + return nil, nil, infraerrors.NotFound("NOT_FOUND", "order not found") + } + ok := []string{OrderStatusCompleted, OrderStatusRefundRequested, OrderStatusRefundFailed} + if !psSliceContains(ok, o.Status) { + return nil, nil, infraerrors.BadRequest("INVALID_STATUS", "order status does not allow refund") + } + if amt <= 0 { + amt = o.Amount + } + if amt > o.Amount { + return nil, nil, infraerrors.BadRequest("REFUND_AMOUNT_EXCEEDED", "refund amount exceeds recharge") + } + ga := amt + if amt == o.Amount { + ga = o.PayAmount + } + rr := strings.TrimSpace(reason) + if rr == "" && o.RefundRequestReason != nil { + rr = *o.RefundRequestReason + } + if rr == "" { + rr = fmt.Sprintf("refund order:%d", o.ID) + } + p := &RefundPlan{OrderID: oid, Order: o, RefundAmount: amt, GatewayAmount: ga, Reason: rr, Force: force, DeductBalance: deduct, DeductionType: "none"} + if deduct { + if er := s.prepDeduct(ctx, o, p, force); er != nil { + return nil, er, nil + } + } + return p, nil, nil +} + +func (s *PaymentService) prepDeduct(ctx context.Context, o *dbent.PaymentOrder, p *RefundPlan, force bool) *RefundResult { + if o.OrderType == "subscription" { + p.DeductionType = "subscription" + return nil + } + u, err := s.userRepo.GetByID(ctx, o.UserID) + if err != nil { + if !force { + return &RefundResult{Success: false, Warning: "cannot fetch user balance, use force", RequireForce: true} + } + return nil + } + p.DeductionType = "balance" + p.BalanceToDeduct = math.Min(p.RefundAmount, u.Balance) + return nil +} + +func (s *PaymentService) ExecuteRefund(ctx context.Context, p *RefundPlan) (*RefundResult, error) { + c, err := s.entClient.PaymentOrder.Update().Where(paymentorder.IDEQ(p.OrderID), paymentorder.StatusIn(OrderStatusCompleted, OrderStatusRefundRequested, OrderStatusRefundFailed)).SetStatus(OrderStatusRefunding).Save(ctx) + if err != nil { + return nil, fmt.Errorf("lock: %w", err) + } + if c == 0 { + return nil, infraerrors.Conflict("CONFLICT", "order status changed") + } + if p.DeductionType == "balance" && p.BalanceToDeduct > 0 { + if err := s.userRepo.DeductBalance(ctx, p.Order.UserID, p.BalanceToDeduct); err != nil { + s.restoreStatus(ctx, p) + return nil, fmt.Errorf("deduction: %w", err) + } + } + if err := s.gwRefund(ctx, p); err != nil { + return s.handleGwFail(ctx, p, err) + } + return s.markRefundOk(ctx, p) +} + +func (s *PaymentService) gwRefund(ctx context.Context, p *RefundPlan) error { + if p.Order.PaymentTradeNo == "" { + s.writeAuditLog(ctx, p.Order.ID, "REFUND_NO_TRADE_NO", "admin", map[string]any{"detail": "skipped"}) + return nil + } + s.EnsureProviders(ctx) + prov, err := s.registry.GetProvider(p.Order.PaymentType) + if err != nil { + return fmt.Errorf("get provider: %w", err) + } + _, err = prov.Refund(ctx, payment.RefundRequest{TradeNo: p.Order.PaymentTradeNo, OrderID: strconv.FormatInt(p.Order.ID, 10), Amount: strconv.FormatFloat(p.GatewayAmount, 'f', 2, 64), Reason: p.Reason}) + return err +} + +func (s *PaymentService) handleGwFail(ctx context.Context, p *RefundPlan, gErr error) (*RefundResult, error) { + if s.RollbackRefund(ctx, p, gErr) { + s.restoreStatus(ctx, p) + s.writeAuditLog(ctx, p.OrderID, "REFUND_GATEWAY_FAILED", "admin", map[string]any{"detail": psErrMsg(gErr)}) + return &RefundResult{Success: false, Warning: "gateway failed: " + psErrMsg(gErr) + ", rolled back"}, nil + } + now := time.Now() + _, _ = s.entClient.PaymentOrder.UpdateOneID(p.OrderID).SetStatus(OrderStatusRefundFailed).SetFailedAt(now).SetFailedReason(psErrMsg(gErr)).Save(ctx) + s.writeAuditLog(ctx, p.OrderID, "REFUND_FAILED", "admin", map[string]any{"detail": psErrMsg(gErr)}) + return nil, infraerrors.InternalServer("REFUND_FAILED", psErrMsg(gErr)) +} + +func (s *PaymentService) markRefundOk(ctx context.Context, p *RefundPlan) (*RefundResult, error) { + fs := OrderStatusRefunded + if p.RefundAmount < p.Order.Amount { + fs = OrderStatusPartiallyRefunded + } + now := time.Now() + _, err := s.entClient.PaymentOrder.UpdateOneID(p.OrderID).SetStatus(fs).SetRefundAmount(p.RefundAmount).SetRefundReason(p.Reason).SetRefundAt(now).SetForceRefund(p.Force).Save(ctx) + if err != nil { + return nil, fmt.Errorf("mark refund: %w", err) + } + s.writeAuditLog(ctx, p.OrderID, "REFUND_SUCCESS", "admin", map[string]any{"refundAmount": p.RefundAmount, "reason": p.Reason, "balanceDeducted": p.BalanceToDeduct, "force": p.Force}) + return &RefundResult{Success: true, BalanceDeducted: p.BalanceToDeduct, SubDaysDeducted: p.SubDaysToDeduct}, nil +} + +func (s *PaymentService) RollbackRefund(ctx context.Context, p *RefundPlan, gErr error) bool { + if p.DeductionType == "balance" && p.BalanceToDeduct > 0 { + if err := s.userRepo.UpdateBalance(ctx, p.Order.UserID, p.BalanceToDeduct); err != nil { + slog.Error("[CRITICAL] rollback failed", "orderID", p.OrderID, "amount", p.BalanceToDeduct, "error", err) + s.writeAuditLog(ctx, p.OrderID, "REFUND_ROLLBACK_FAILED", "admin", map[string]any{"gatewayError": psErrMsg(gErr), "rollbackError": psErrMsg(err), "balanceDeducted": p.BalanceToDeduct}) + return false + } + } + return true +} + +func (s *PaymentService) restoreStatus(ctx context.Context, p *RefundPlan) { + rs := OrderStatusCompleted + if p.Order.Status == OrderStatusRefundRequested { + rs = OrderStatusRefundRequested + } + _, _ = s.entClient.PaymentOrder.UpdateOneID(p.OrderID).SetStatus(rs).Save(ctx) +} + +func (s *PaymentService) ExpireTimedOutOrders(ctx context.Context) (int, error) { + now := time.Now() + orders, err := s.entClient.PaymentOrder.Query().Where(paymentorder.StatusEQ(OrderStatusPending), paymentorder.ExpiresAtLTE(now)).All(ctx) + if err != nil { + return 0, fmt.Errorf("query expired: %w", err) + } + n := 0 + for _, o := range orders { + c, e := s.entClient.PaymentOrder.Update().Where(paymentorder.IDEQ(o.ID), paymentorder.StatusEQ(OrderStatusPending)).SetStatus(OrderStatusExpired).Save(ctx) + if e != nil { + slog.Warn("expire failed", "orderID", o.ID, "error", e) + continue + } + if c > 0 { + s.writeAuditLog(ctx, o.ID, "ORDER_EXPIRED", "system", map[string]any{"expiresAt": o.ExpiresAt.Format(time.RFC3339)}) + n++ + } + } + return n, nil +} +func (s *PaymentService) GetDashboardStats(ctx context.Context, days int) (*DashboardStats, error) { + if days <= 0 { + days = 30 + } + now := time.Now() + since := now.AddDate(0, 0, -days) + todayStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) + + paidStatuses := []string{OrderStatusCompleted, OrderStatusPaid, OrderStatusRecharging} + + // Fetch all paid orders in the date range + orders, err := s.entClient.PaymentOrder.Query(). + Where( + paymentorder.StatusIn(paidStatuses...), + paymentorder.PaidAtGTE(since), + ). + All(ctx) + if err != nil { + return nil, err + } + + st := &DashboardStats{} + + // Compute basic stats + var totalAmount float64 + var todayAmount float64 + var todayCount int + for _, o := range orders { + totalAmount += o.PayAmount + if o.PaidAt != nil && !o.PaidAt.Before(todayStart) { + todayAmount += o.PayAmount + todayCount++ + } + } + st.TotalAmount = math.Round(totalAmount*100) / 100 + st.TodayAmount = math.Round(todayAmount*100) / 100 + st.TotalCount = len(orders) + st.TodayCount = todayCount + if st.TotalCount > 0 { + st.AvgAmount = math.Round(totalAmount/float64(st.TotalCount)*100) / 100 + } + + // Pending orders count + st.PendingOrders, err = s.entClient.PaymentOrder.Query(). + Where(paymentorder.StatusEQ(OrderStatusPending)). + Count(ctx) + if err != nil { + return nil, err + } + + // Daily series: GROUP BY date(paid_at) + dailyMap := make(map[string]*DailyStats) + for _, o := range orders { + if o.PaidAt == nil { + continue + } + date := o.PaidAt.Format("2006-01-02") + ds, ok := dailyMap[date] + if !ok { + ds = &DailyStats{Date: date} + dailyMap[date] = ds + } + ds.Amount += o.PayAmount + ds.Count++ + } + // Build sorted daily series for all days in range + st.DailySeries = make([]DailyStats, 0, days) + for i := 0; i < days; i++ { + date := since.AddDate(0, 0, i+1).Format("2006-01-02") + if ds, ok := dailyMap[date]; ok { + ds.Amount = math.Round(ds.Amount*100) / 100 + st.DailySeries = append(st.DailySeries, *ds) + } else { + st.DailySeries = append(st.DailySeries, DailyStats{Date: date}) + } + } + + // Payment methods: GROUP BY payment_type + methodMap := make(map[string]*PaymentMethodStat) + for _, o := range orders { + ms, ok := methodMap[o.PaymentType] + if !ok { + ms = &PaymentMethodStat{Type: o.PaymentType} + methodMap[o.PaymentType] = ms + } + ms.Amount += o.PayAmount + ms.Count++ + } + st.PaymentMethods = make([]PaymentMethodStat, 0, len(methodMap)) + for _, ms := range methodMap { + ms.Amount = math.Round(ms.Amount*100) / 100 + st.PaymentMethods = append(st.PaymentMethods, *ms) + } + + // Top users: GROUP BY user_id, ORDER BY amount DESC, LIMIT 10 + userMap := make(map[int64]*TopUserStat) + for _, o := range orders { + us, ok := userMap[o.UserID] + if !ok { + us = &TopUserStat{UserID: o.UserID, Email: o.UserEmail} + userMap[o.UserID] = us + } + us.Amount += o.PayAmount + } + type userEntry struct { + stat *TopUserStat + amount float64 + } + userList := make([]userEntry, 0, len(userMap)) + for _, us := range userMap { + us.Amount = math.Round(us.Amount*100) / 100 + userList = append(userList, userEntry{stat: us, amount: us.Amount}) + } + // Sort descending by amount + for i := 0; i < len(userList); i++ { + for j := i + 1; j < len(userList); j++ { + if userList[j].amount > userList[i].amount { + userList[i], userList[j] = userList[j], userList[i] + } + } + } + limit := 10 + if len(userList) < limit { + limit = len(userList) + } + st.TopUsers = make([]TopUserStat, 0, limit) + for i := 0; i < limit; i++ { + st.TopUsers = append(st.TopUsers, *userList[i].stat) + } + + return st, nil +} + +func (s *PaymentService) sumAmt(ctx context.Context, statuses []string, since time.Time, usePaid bool) (float64, error) { + q := s.entClient.PaymentOrder.Query().Where(paymentorder.StatusIn(statuses...)) + if usePaid { + q = q.Where(paymentorder.PaidAtGTE(since)) + } else { + q = q.Where(paymentorder.CreatedAtGTE(since)) + } + os, err := q.All(ctx) + if err != nil { + return 0, err + } + var t float64 + for _, o := range os { + if usePaid { + t += o.Amount + } else { + t += o.RefundAmount + } + } + return t, nil +} + +func (s *PaymentService) writeAuditLog(ctx context.Context, oid int64, action, op string, detail map[string]any) { + dj, _ := json.Marshal(detail) + _, err := s.entClient.PaymentAuditLog.Create().SetOrderID(strconv.FormatInt(oid, 10)).SetAction(action).SetDetail(string(dj)).SetOperator(op).Save(ctx) + if err != nil { + slog.Error("audit log failed", "orderID", oid, "action", action, "error", err) + } +} + +func (s *PaymentService) GetOrderAuditLogs(ctx context.Context, oid int64) ([]*dbent.PaymentAuditLog, error) { + return s.entClient.PaymentAuditLog.Query().Where(paymentauditlog.OrderIDEQ(strconv.FormatInt(oid, 10))).Order(paymentauditlog.ByCreatedAt()).All(ctx) +} + +func psIsRefundStatus(s string) bool { + switch s { + case OrderStatusRefundRequested, OrderStatusRefunding, OrderStatusPartiallyRefunded, OrderStatusRefunded, OrderStatusRefundFailed: + return true + } + return false +} + +func psErrMsg(err error) string { + if err == nil { + return "" + } + return err.Error() +} + +func psNilIfEmpty(s string) *string { + if s == "" { + return nil + } + return &s +} + +func psSliceContains(sl []string, s string) bool { + for _, v := range sl { + if v == s { + return true + } + } + return false +} + +func psComputeValidityDays(days int, unit string) int { + switch unit { + case "week": + return days * 7 + case "month": + return days * 30 + default: + return days + } +} + +func (s *PaymentService) getFeeRate(_ string) float64 { return 0 } + +func psStartOfDayUTC(t time.Time) time.Time { + y, m, d := t.UTC().Date() + return time.Date(y, m, d, 0, 0, 0, 0, time.UTC) +} + +// AdminListOrders returns a paginated list of orders. If userID > 0, filters by user. +func (s *PaymentService) AdminListOrders(ctx context.Context, userID int64, p OrderListParams) ([]*dbent.PaymentOrder, int, error) { + q := s.entClient.PaymentOrder.Query() + if userID > 0 { + q = q.Where(paymentorder.UserIDEQ(userID)) + } + if p.Status != "" { + q = q.Where(paymentorder.StatusEQ(p.Status)) + } + if p.OrderType != "" { + q = q.Where(paymentorder.OrderTypeEQ(p.OrderType)) + } + if p.PaymentType != "" { + q = q.Where(paymentorder.PaymentTypeEQ(p.PaymentType)) + } + total, err := q.Clone().Count(ctx) + if err != nil { + return nil, 0, fmt.Errorf("count admin orders: %w", err) + } + ps := p.PageSize + if ps <= 0 { + ps = 20 + } + if ps > 100 { + ps = 100 + } + pg := p.Page + if pg < 1 { + pg = 1 + } + orders, err := q.Order(dbent.Desc(paymentorder.FieldCreatedAt)).Limit(ps).Offset((pg - 1) * ps).All(ctx) + if err != nil { + return nil, 0, fmt.Errorf("query admin orders: %w", err) + } + return orders, total, nil +} + +// EnsureProviders lazily initializes the provider registry on first call. +// It queries all enabled PaymentProviderInstance records, decrypts their config, +// creates providers via provider.CreateProvider, and registers them. +func (s *PaymentService) EnsureProviders(ctx context.Context) { + s.providerMu.Lock() + defer s.providerMu.Unlock() + if s.providersLoaded { + return + } + s.loadProviders(ctx) + s.providersLoaded = true +} + +// RefreshProviders clears and re-registers all providers from the database. +// Call this when provider instances are created, updated, or deleted. +func (s *PaymentService) RefreshProviders(ctx context.Context) { + s.providerMu.Lock() + defer s.providerMu.Unlock() + s.registry.Clear() + s.loadProviders(ctx) + s.providersLoaded = true +} + +func (s *PaymentService) loadProviders(ctx context.Context) { + instances, err := s.entClient.PaymentProviderInstance.Query(). + Where(paymentproviderinstance.EnabledEQ(true)). + All(ctx) + if err != nil { + slog.Error("[PaymentService] failed to query provider instances", "error", err) + return + } + for _, inst := range instances { + cfg, err := s.loadBalancer.GetInstanceConfig(ctx, int64(inst.ID)) + if err != nil { + slog.Warn("[PaymentService] failed to decrypt config for instance", "instanceID", inst.ID, "error", err) + continue + } + instID := fmt.Sprintf("%d", inst.ID) + p, err := provider.CreateProvider(inst.ProviderKey, instID, cfg) + if err != nil { + slog.Warn("[PaymentService] failed to create provider for instance", "instanceID", inst.ID, "key", inst.ProviderKey, "error", err) + continue + } + s.registry.Register(p) + } + slog.Info("[PaymentService] registered payment types", "types", len(s.registry.SupportedTypes()), "instances", len(instances)) +} diff --git a/backend/internal/service/wire.go b/backend/internal/service/wire.go index d66d8cff86..a8ece8a38c 100644 --- a/backend/internal/service/wire.go +++ b/backend/internal/service/wire.go @@ -5,7 +5,9 @@ import ( "database/sql" "time" + dbent "github.com/Wei-Shaw/sub2api/ent" "github.com/Wei-Shaw/sub2api/internal/config" + "github.com/Wei-Shaw/sub2api/internal/payment" "github.com/Wei-Shaw/sub2api/internal/pkg/logger" "github.com/google/wire" "github.com/redis/go-redis/v9" @@ -460,4 +462,20 @@ var ProviderSet = wire.NewSet( NewGroupCapacityService, NewChannelService, NewModelPricingResolver, + ProvidePaymentConfigService, + NewPaymentService, + ProvidePaymentOrderExpiryService, ) + +// ProvidePaymentConfigService wraps NewPaymentConfigService to accept the named +// payment.EncryptionKey type instead of raw []byte, avoiding Wire ambiguity. +func ProvidePaymentConfigService(entClient *dbent.Client, settingRepo SettingRepository, key payment.EncryptionKey) *PaymentConfigService { + return NewPaymentConfigService(entClient, settingRepo, []byte(key)) +} + +// ProvidePaymentOrderExpiryService creates and starts PaymentOrderExpiryService. +func ProvidePaymentOrderExpiryService(paymentSvc *PaymentService) *PaymentOrderExpiryService { + svc := NewPaymentOrderExpiryService(paymentSvc, 60*time.Second) + svc.Start() + return svc +} diff --git a/backend/migrations/090_payment_orders.sql b/backend/migrations/090_payment_orders.sql new file mode 100644 index 0000000000..036e4dedc0 --- /dev/null +++ b/backend/migrations/090_payment_orders.sql @@ -0,0 +1,47 @@ +CREATE TABLE IF NOT EXISTS payment_orders ( + id BIGSERIAL PRIMARY KEY, + user_id BIGINT NOT NULL, + user_email VARCHAR(255) NOT NULL DEFAULT '', + user_name VARCHAR(100) NOT NULL DEFAULT '', + user_notes TEXT, + amount DECIMAL(20,2) NOT NULL, + pay_amount DECIMAL(20,2) NOT NULL, + fee_rate DECIMAL(10,4) NOT NULL DEFAULT 0, + recharge_code VARCHAR(64) NOT NULL DEFAULT '', + payment_type VARCHAR(30) NOT NULL DEFAULT '', + payment_trade_no VARCHAR(128) NOT NULL DEFAULT '', + pay_url TEXT, + qr_code TEXT, + qr_code_img TEXT, + order_type VARCHAR(20) NOT NULL DEFAULT 'balance', + plan_id BIGINT, + subscription_group_id BIGINT, + subscription_days INT, + provider_instance_id VARCHAR(64), + status VARCHAR(30) NOT NULL DEFAULT 'PENDING', + refund_amount DECIMAL(20,2) NOT NULL DEFAULT 0, + refund_reason TEXT, + refund_at TIMESTAMPTZ, + force_refund BOOLEAN NOT NULL DEFAULT FALSE, + refund_requested_at TIMESTAMPTZ, + refund_request_reason TEXT, + refund_requested_by VARCHAR(20), + expires_at TIMESTAMPTZ NOT NULL, + paid_at TIMESTAMPTZ, + completed_at TIMESTAMPTZ, + failed_at TIMESTAMPTZ, + failed_reason TEXT, + client_ip VARCHAR(50) NOT NULL DEFAULT '', + src_host VARCHAR(255) NOT NULL DEFAULT '', + src_url TEXT, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); +-- Indexes +CREATE INDEX IF NOT EXISTS idx_payment_orders_user_id ON payment_orders(user_id); +CREATE INDEX IF NOT EXISTS idx_payment_orders_status ON payment_orders(status); +CREATE INDEX IF NOT EXISTS idx_payment_orders_expires_at ON payment_orders(expires_at); +CREATE INDEX IF NOT EXISTS idx_payment_orders_created_at ON payment_orders(created_at); +CREATE INDEX IF NOT EXISTS idx_payment_orders_paid_at ON payment_orders(paid_at); +CREATE INDEX IF NOT EXISTS idx_payment_orders_type_paid ON payment_orders(payment_type, paid_at); +CREATE INDEX IF NOT EXISTS idx_payment_orders_order_type ON payment_orders(order_type); diff --git a/backend/migrations/091_payment_audit_logs.sql b/backend/migrations/091_payment_audit_logs.sql new file mode 100644 index 0000000000..d05b15ef83 --- /dev/null +++ b/backend/migrations/091_payment_audit_logs.sql @@ -0,0 +1,9 @@ +CREATE TABLE IF NOT EXISTS payment_audit_logs ( + id BIGSERIAL PRIMARY KEY, + order_id VARCHAR(64) NOT NULL, + action VARCHAR(50) NOT NULL, + detail TEXT NOT NULL DEFAULT '', + operator VARCHAR(100) NOT NULL DEFAULT 'system', + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); +CREATE INDEX IF NOT EXISTS idx_payment_audit_logs_order_id ON payment_audit_logs(order_id); diff --git a/backend/migrations/092_removed_payment_channels.sql b/backend/migrations/092_removed_payment_channels.sql new file mode 100644 index 0000000000..cb20234795 --- /dev/null +++ b/backend/migrations/092_removed_payment_channels.sql @@ -0,0 +1,4 @@ +-- Migration 092: payment_channels table was removed before release. +-- This file is a no-op placeholder to maintain migration numbering continuity. +-- The payment system now uses the existing channels table (migration 081). +SELECT 1; diff --git a/backend/migrations/093_subscription_plans.sql b/backend/migrations/093_subscription_plans.sql new file mode 100644 index 0000000000..541d8f0c89 --- /dev/null +++ b/backend/migrations/093_subscription_plans.sql @@ -0,0 +1,18 @@ +CREATE TABLE IF NOT EXISTS subscription_plans ( + id BIGSERIAL PRIMARY KEY, + group_id BIGINT NOT NULL, + name VARCHAR(100) NOT NULL, + description TEXT NOT NULL DEFAULT '', + price DECIMAL(20,2) NOT NULL, + original_price DECIMAL(20,2), + validity_days INT NOT NULL DEFAULT 30, + validity_unit VARCHAR(10) NOT NULL DEFAULT 'day', + features TEXT NOT NULL DEFAULT '', + product_name VARCHAR(100) NOT NULL DEFAULT '', + for_sale BOOLEAN NOT NULL DEFAULT TRUE, + sort_order INT NOT NULL DEFAULT 0, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); +CREATE INDEX IF NOT EXISTS idx_subscription_plans_group_id ON subscription_plans(group_id); +CREATE INDEX IF NOT EXISTS idx_subscription_plans_for_sale ON subscription_plans(for_sale); diff --git a/backend/migrations/094_payment_provider_instances.sql b/backend/migrations/094_payment_provider_instances.sql new file mode 100644 index 0000000000..bedd75df60 --- /dev/null +++ b/backend/migrations/094_payment_provider_instances.sql @@ -0,0 +1,15 @@ +CREATE TABLE IF NOT EXISTS payment_provider_instances ( + id BIGSERIAL PRIMARY KEY, + provider_key VARCHAR(30) NOT NULL, + name VARCHAR(100) NOT NULL DEFAULT '', + config TEXT NOT NULL, + supported_types VARCHAR(200) NOT NULL DEFAULT '', + enabled BOOLEAN NOT NULL DEFAULT TRUE, + sort_order INT NOT NULL DEFAULT 0, + limits TEXT NOT NULL DEFAULT '', + refund_enabled BOOLEAN NOT NULL DEFAULT FALSE, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); +CREATE INDEX IF NOT EXISTS idx_payment_provider_instances_provider_key ON payment_provider_instances(provider_key); +CREATE INDEX IF NOT EXISTS idx_payment_provider_instances_enabled ON payment_provider_instances(enabled); diff --git a/backend/migrations/095_channel_features.sql b/backend/migrations/095_channel_features.sql new file mode 100644 index 0000000000..5f14200272 --- /dev/null +++ b/backend/migrations/095_channel_features.sql @@ -0,0 +1,2 @@ +ALTER TABLE channels ADD COLUMN IF NOT EXISTS features TEXT NOT NULL DEFAULT ''; +COMMENT ON COLUMN channels.features IS '渠道特性描述,JSON 数组格式,用于支付页面展示'; diff --git a/docs/PAYMENT_BACKEND_MIGRATION_PLAN.md b/docs/PAYMENT_BACKEND_MIGRATION_PLAN.md new file mode 100644 index 0000000000..6929163c65 --- /dev/null +++ b/docs/PAYMENT_BACKEND_MIGRATION_PLAN.md @@ -0,0 +1,298 @@ +# 支付系统 Go 后端实现计划 + +> 将 sub2apipay (TypeScript/Prisma) 后端逻辑迁移到 sub2api (Go/Ent) +> +> 分支: `feature/payment` (基于 upstream `Wei-Shaw/sub2api:main`) + +--- + +## 一、新增 Ent Schema (5 个) + +| Schema | 表名 | 说明 | +|--------|------|------| +| PaymentOrder | payment_orders | 充值/订阅订单 | +| PaymentAuditLog | payment_audit_logs | 订单审计日志 | +| PaymentChannel | payment_channels | 展示渠道 | +| SubscriptionPlan | subscription_plans | 订阅套餐 | +| PaymentProviderInstance | payment_provider_instances | 支付服务商实例 | + +所有表使用 `payment_` 前缀避免与现有表冲突。 + +### PaymentOrder 字段 + +- user_id, user_email, user_name, user_notes +- amount(充值额), pay_amount(实付), fee_rate, recharge_code +- payment_type, payment_trade_no, pay_url, qr_code, qr_code_img +- order_type(balance/subscription), plan_id, subscription_group_id, subscription_days +- provider_instance_id +- status (PENDING/PAID/RECHARGING/COMPLETED/EXPIRED/CANCELLED/FAILED/REFUND_REQUESTED/REFUNDING/PARTIALLY_REFUNDED/REFUNDED/REFUND_FAILED) +- refund_amount, refund_reason, refund_at, force_refund, refund_requested_at, refund_request_reason, refund_requested_by +- expires_at, paid_at, completed_at, failed_at, failed_reason +- client_ip, src_host, src_url +- created_at, updated_at +- 索引: user_id, status, expires_at, created_at, paid_at, (payment_type,paid_at), order_type + +### PaymentAuditLog 字段 + +- order_id, action, detail, operator, created_at + +### PaymentChannel 字段 + +- group_id(关联sub2api Group), name, platform, rate_multiplier, description, models(JSON), features(JSON), sort_order, enabled, created_at, updated_at + +### SubscriptionPlan 字段 + +- group_id, name, description, price, original_price, validity_days, validity_unit(day/week/month), features(JSON), product_name, for_sale, sort_order, created_at, updated_at + +### PaymentProviderInstance 字段 + +- provider_key(easypay/alipay/wxpay/stripe), name, config(AES加密JSON), supported_types, enabled, sort_order, limits(JSON), refund_enabled, created_at, updated_at + +--- + +## 二、Go 接口定义 + +### 2.1 Provider 接口 + +```go +// internal/payment/types.go +type Provider interface { + Name() string + ProviderKey() string + SupportedTypes() []PaymentType + CreatePayment(ctx context.Context, req CreatePaymentRequest) (*CreatePaymentResponse, error) + QueryOrder(ctx context.Context, tradeNo string) (*QueryOrderResponse, error) + VerifyNotification(ctx context.Context, body []byte, headers map[string]string) (*PaymentNotification, error) + Refund(ctx context.Context, req RefundRequest) (*RefundResponse, error) +} + +type CancelableProvider interface { + Provider + CancelPayment(ctx context.Context, tradeNo string) error +} +``` + +### 2.2 Registry + +```go +// internal/payment/registry.go +type Registry struct { + providers map[string]Provider // providerKey -> Provider + typeMap map[PaymentType]string // paymentType -> providerKey +} + +func (r *Registry) Register(p Provider) +func (r *Registry) GetProvider(paymentType PaymentType) (Provider, error) +func (r *Registry) GetProviderKey(paymentType PaymentType) string +func (r *Registry) SupportedTypes() []PaymentType +``` + +### 2.3 LoadBalancer + +```go +// internal/payment/load_balancer.go +type LoadBalancer interface { + SelectInstance(ctx context.Context, providerKey string, paymentType PaymentType) (*InstanceSelection, error) +} +``` + +--- + +## 三、Service 层 + +### 3.1 PaymentService — 订单全生命周期 + +```go +// 直接注入现有 service,不走 HTTP +type PaymentService struct { + db *ent.Client + registry *payment.Registry + loadBalancer payment.LoadBalancer + redeemService *RedeemService // 余额充值直接调用 + subscriptionSvc *SubscriptionService // 订阅激活直接调用 + adminService AdminService // 余额扣减 + configService *PaymentConfigService +} + +// 订单 +CreateOrder / GetOrder / GetUserOrders / CancelOrder / AdminCancelOrder +// 支付确认 & 履约 +HandlePaymentNotification / ExecuteBalanceFulfillment / ExecuteSubscriptionFulfillment / RetryFulfillment +// 退款三阶段 +RequestRefund / PrepareRefund / ExecuteRefund / RollbackRefund +// 超时 +ExpireTimedOutOrders +// 统计 +GetDashboardStats +``` + +### 3.2 PaymentConfigService — 配置 & CRUD + +```go +type PaymentConfigService struct { + db *ent.Client + settingService *SettingService // 复用现有 Setting 表 + encryptionKey []byte +} + +// 系统配置 +IsPaymentEnabled / GetPaymentConfig / UpdatePaymentConfig +// 服务商实例 CRUD +ListProviderInstances / CreateProviderInstance / UpdateProviderInstance / DeleteProviderInstance +// 渠道 CRUD +ListChannels / CreateChannel / UpdateChannel / DeleteChannel +// 套餐 CRUD +ListPlans / CreatePlan / UpdatePlan / DeletePlan +// 手续费 & 限额 +GetMethodLimits / CalculatePayAmount +``` + +### 3.3 关键差异 vs sub2apipay + +| 维度 | sub2apipay (TS) | sub2api (Go) | +|------|-----------------|-------------| +| 余额充值 | HTTP 调 sub2api API | 直接调 RedeemService | +| 订阅激活 | HTTP 调 sub2api API | 直接调 SubscriptionService | +| 用户验证 | HTTP 调 /api/v1/auth/me | JWT middleware 已处理 | +| Decimal | Prisma.Decimal | shopspring/decimal | +| 加密 | Node.js crypto | Go crypto/aes + cipher | +| 配置存储 | SystemConfig 表 | 复用现有 Setting 表 | + +--- + +## 四、Handler 层 & API 端点 + +### 4.1 用户端 (9 个) + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | /api/v1/payment/config | 支付配置 | +| GET | /api/v1/payment/plans | 套餐列表 | +| GET | /api/v1/payment/channels | 渠道列表 | +| GET | /api/v1/payment/limits | 支付方式限额 | +| POST | /api/v1/payment/orders | 创建订单 | +| GET | /api/v1/payment/orders/my | 用户订单列表 | +| GET | /api/v1/payment/orders/:id | 订单详情 | +| POST | /api/v1/payment/orders/:id/cancel | 取消订单 | +| POST | /api/v1/payment/orders/:id/refund-request | 申请退款 | + +### 4.2 Webhook (4 个,无需认证) + +| 方法 | 路径 | 说明 | +|------|------|------| +| POST | /api/v1/payment/webhook/easypay | EasyPay 回调 | +| POST | /api/v1/payment/webhook/alipay | 支付宝回调 | +| POST | /api/v1/payment/webhook/wxpay | 微信支付回调 | +| POST | /api/v1/payment/webhook/stripe | Stripe Webhook | + +### 4.3 管理端 (18 个) + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | /admin/payment/dashboard | 仪表盘 | +| GET | /admin/payment/orders | 订单列表 | +| GET | /admin/payment/orders/:id | 订单详情 | +| POST | /admin/payment/orders/:id/cancel | 取消订单 | +| POST | /admin/payment/orders/:id/retry | 重试充值 | +| POST | /admin/payment/orders/:id/refund | 处理退款 | +| GET/POST | /admin/payment/channels | 渠道列表/创建 | +| PUT/DELETE | /admin/payment/channels/:id | 更新/删除 | +| GET/POST | /admin/payment/plans | 套餐列表/创建 | +| PUT/DELETE | /admin/payment/plans/:id | 更新/删除 | +| GET/POST | /admin/payment/providers | 实例列表/创建 | +| PUT/DELETE | /admin/payment/providers/:id | 更新/删除 | + +--- + +## 五、Provider 实现 + +### 目录结构 + +``` +internal/payment/ +├── types.go, registry.go, load_balancer.go, fee.go, crypto.go, wire.go +├── provider_factory.go +└── provider/ + ├── easypay.go # 纯 HTTP + MD5 (无需 SDK) + ├── alipay.go # smartwalle/alipay/v3 SDK + ├── wxpay.go # wechatpay-apiv3/wechatpay-go 官方 SDK + └── stripe.go # stripe/stripe-go 官方 SDK +``` + +### Go 依赖 + +| 包 | 用途 | +|----|------| +| github.com/stripe/stripe-go/v82 | Stripe 官方 | +| github.com/wechatpay-apiv3/wechatpay-go | 微信支付官方 | +| github.com/smartwalle/alipay/v3 | 支付宝 | +| github.com/shopspring/decimal | 精确十进制 | + +--- + +## 六、数据库迁移 (5 个 SQL 文件) + +``` +migrations/090_payment_orders.sql +migrations/091_payment_audit_logs.sql +migrations/092_payment_channels.sql +migrations/093_subscription_plans.sql +migrations/094_payment_provider_instances.sql +``` + +--- + +## 七、Wire DI + +```go +// internal/payment/wire.go +var ProviderSet = wire.NewSet( + NewRegistry, NewLoadBalancer, + NewPaymentConfigService, NewPaymentService, + NewPaymentHandler, NewPaymentAdminHandler, NewPaymentWebhookHandler, +) +``` + +--- + +## 八、路由注册 + +```go +// internal/server/routes/payment.go +func RegisterPaymentRoutes(v1 *gin.RouterGroup, h *handler.Handlers, jwtAuth, adminAuth middleware) +``` + +在 router.go 的 registerRoutes() 中新增: +```go +routes.RegisterPaymentRoutes(v1, h, jwtAuth, adminAuth) +``` + +--- + +## 九、新增文件清单 (~25 个 Go + 5 个 SQL) + +**payment 核心 (8)**: +- internal/payment/types.go, registry.go, load_balancer.go +- internal/payment/fee.go, crypto.go, wire.go, provider_factory.go + +**provider 实现 (4)**: +- internal/payment/provider/easypay.go, alipay.go, wxpay.go, stripe.go + +**service (2)**: +- internal/service/payment_service.go, payment_config_service.go + +**handler (3)**: +- internal/handler/payment_handler.go, payment_webhook_handler.go +- internal/handler/admin/payment_handler.go + +**routes (1)**: +- internal/server/routes/payment.go + +**schema (5)**: +- ent/schema/payment_order.go, payment_audit_log.go, payment_channel.go +- ent/schema/subscription_plan.go, payment_provider_instance.go + +**migration (5)**: +- migrations/090-094 + +**Ent generate**: 运行 `go generate ./ent` 生成 CRUD 代码 diff --git a/docs/PAYMENT_FRONTEND_MIGRATION_PLAN.md b/docs/PAYMENT_FRONTEND_MIGRATION_PLAN.md new file mode 100644 index 0000000000..d5df308a64 --- /dev/null +++ b/docs/PAYMENT_FRONTEND_MIGRATION_PLAN.md @@ -0,0 +1,730 @@ +# 支付系统前端迁移计划 + +> 将 sub2apipay (Next.js/React) 的支付功能原生集成到 sub2api (Vue3) 前端中 +> +> 分支: `feature/payment` (基于 upstream `Wei-Shaw/sub2api:main`) + +--- + +## 一、迁移概述 + +### 1.1 现状 + +当前 sub2api 通过 **iframe 嵌入外部 URL** 的方式提供充值/订阅功能: + +- 管理员在 `系统设置 → General tab` 中配置 `purchase_subscription_url` +- 用户侧边栏出现"充值/订阅"菜单项(受 `purchase_subscription_enabled` 控制) +- 点击后在 `PurchaseSubscriptionView.vue` 中以 iframe 加载外部页面 +- 外部页面(sub2apipay)通过 URL 参数接收 `user_id`, `token`, `theme`, `lang` + +**现有关键文件:** + +| 文件 | 作用 | +|------|------| +| `src/components/layout/AppSidebar.vue` | 侧边栏菜单定义(~700行) | +| `src/views/user/PurchaseSubscriptionView.vue` | iframe 嵌入页(~159行��� | +| `src/views/admin/SettingsView.vue` | 管理后台设置页(~2500行) | +| `src/stores/app.ts` | 公共设置存储(含 `purchase_subscription_enabled`) | +| `src/stores/adminSettings.ts` | 管理设置存储 | +| `src/router/index.ts` | 路由定义 | +| `src/i18n/locales/en.ts` / `zh.ts` | 国际化文本 | +| `src/utils/embedded-url.ts` | iframe URL 构建工具 | + +### 1.2 目标 + +将 sub2apipay 的所有前端功能原生实现为 Vue3 组件,集成到 sub2api 项目中: + +- **消除 iframe** — 所有支付、订单页面变为原生 Vue 组件 +- **消除外部依赖** — 不再需要独立部署 sub2apipay +- **直接调用后端 API** — 替代 HTTP 跨域调用 +- **统一认证** — 复用 sub2api 的 JWT 认证,无需 URL 传 token +- **统一 UI** — 使用 sub2api 现有的 TailwindCSS 设计系统和组件库 + +--- + +## 二、菜单结构变更 + +### 2.1 管理员侧边栏 (`adminNavItems`) + +**当前菜单(upstream main):** + +``` +仪表盘 /admin/dashboard +运维监控 /admin/ops (ops_monitoring_enabled 控制) +用户管理 /admin/users +分组管理 /admin/groups +渠道管理 /admin/channels +订阅管理 /admin/subscriptions +账号管理 /admin/accounts +公告管理 /admin/announcements +代理管理 /admin/proxies +充值码管理 /admin/redeem +推广码管理 /admin/promo-codes +用量统计 /admin/usage +系统设置 /admin/settings +[自定义菜单] +``` + +**迁移后菜单:** + +``` +仪表盘 /admin/dashboard +运维监控 /admin/ops (ops_monitoring_enabled 控制) +用户管理 /admin/users +分组管理 /admin/groups +渠道管理 /admin/channels +订阅管理 /admin/subscriptions +账号管理 /admin/accounts +公告管理 /admin/announcements +代理管理 /admin/proxies +充值码管理 /admin/redeem +推广码管理 /admin/promo-codes ++ 订单管理 /admin/orders ← 新增(payment_enabled 控制可见性) +用量统计 /admin/usage +系统设置 /admin/settings +[自定义菜单] +``` + +**新增"订单管理"菜单及子菜单:** + +"订单管理"作为一级菜单项,点击后页面内部提供 tab 导航: + +| 子菜单 | 路由 | 说明 | +|--------|------|------| +| 订单概览 | `/admin/orders` | 订单统计仪表盘(日收入、支付方式分布、排行榜) | +| 订单列表 | `/admin/orders/list` | 订单搜索/筛选/详情/退款操作 | +| 渠道管理 | `/admin/orders/channels` | 支付渠道定义(展示名称、倍率、描述) | +| 订阅套餐 | `/admin/orders/plans` | 订阅计划管理(价格、有效期、分组绑定) | + +> **可见性规则**: 仅当系统设置中"充值/订阅功能"开启时,"订单管理"菜单才可见。 + +### 2.2 用户侧边栏 (`userNavItems`) + +**当前菜单:** + +``` +仪表盘 /dashboard +API密钥 /keys +用量统计 /usage +我的订阅 /subscriptions +[Sora] /sora (sora_client_enabled 控制) +[充值/订阅] /purchase (purchase_subscription_enabled 控制, iframe) +兑换码 /redeem +个人设置 /profile +[自定义菜单] +``` + +**迁移后菜单:** + +``` +仪表盘 /dashboard +API密钥 /keys +用量统计 /usage +我的订阅 /subscriptions +[Sora] /sora (sora_client_enabled 控制) +- [充值/订阅] /purchase ← 替换: 不再是 iframe ++ 充值/订阅 /purchase ← 原生 Vue 页面(payment_enabled 控制) ++ 我的订单 /orders ← 新增(payment_enabled 控制) +兑换码 /redeem +个人设置 /profile +[自定义菜单] +``` + +**变更要点:** + +1. `/purchase` 路由保持不变,但组件从 iframe 替换为原生 `PaymentView.vue` +2. 新增 `/orders` 路由 — "我的订单"页面 +3. 菜单可见性条件从 `purchase_subscription_enabled` 变更为 `payment_enabled` +4. 移除 `purchase_subscription_url` 设置项 + +### 2.3 管理员"我的账户"区域 (`personalNavItems`) + +与 `userNavItems` 保持一致的变更:增加"我的订单",替换"充值/订阅"为原生页面。 + +--- + +## 三、系统设置变更 + +### 3.1 Settings Tab 变更 + +**当前 tabs:** + +``` +general | security | users | gateway | email | backup | data +``` + +**迁移后 tabs:** + +``` +general | security | users | gateway | payment | email | backup | data +``` + +新增 **`payment`** tab,在 `gateway` 之后、`email` 之前。 + +### 3.2 `payment` Tab 内容 + +此 tab 替代原 `general` tab 中的"充值/订阅页面"配置区块。 + +**配置项设计:** + +``` +┌─────────────────────────────────────────────────────────┐ +│ 充值/订阅功能 │ +│ ───────────────────────────────────── │ +│ 启用充值/订阅 [Toggle] │ +│ 说明: 开启后用户可通过在线支付充值余额或购买订阅。 │ +│ 同时"订单管理"菜单将对管理员可见。 │ +│ │ +│ (以下配置仅在功能启用后显示) │ +│ │ +│ ┌─ 基本设置 ──────────────────────────────────────────┐ │ +│ │ 最低充值金额 [___] 元 │ │ +│ │ 最高充值金额 [___] 元 │ │ +│ │ 每日充值限额 [___] 元 │ │ +│ │ 最大待支付订单数 [___] │ │ +│ │ 订单超时时间 [___] 分钟 │ │ +│ │ 禁用余额支付 [Toggle] │ │ +│ └──────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─ 支付服务商 ────────────────────────────────────────┐ │ +│ │ 启用的支付方式 [☑ 支付宝] [☑ 微信支付] [☑ Stripe] │ │ +│ │ │ │ +│ │ 服务商实例管理 [管理实例 →] │ │ +│ │ (跳转到服务商实例配置子页面) │ │ +│ └──────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─ 显示设置 ──────────────────────────────────────────┐ │ +│ │ 帮助图片 URL [___] │ │ +│ │ 帮助文字 [___] │ │ +│ └──────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────┘ +``` + +### 3.3 从 `general` Tab 移除的内容 + +原 `general` tab 中的以下配置区块将移除: + +- **"Recharge / Subscription Page"** 整个 card + +### 3.4 旧版兼容:自定义页面迁移 + +对于已使用 `purchase_subscription_url` 配置外部支付页面的用户: + +- 数据库迁移脚本检查 `purchase_subscription_url` 是否有值 +- 若有值,自动创建一个"自定义菜单页面" (custom_menu_item),保留原 URL +- 确保旧版用户升级后,原来的外部支付页面仍可通过自定义菜单访问 +- `purchase_subscription_enabled` 和 `purchase_subscription_url` 设置项保留但标记 deprecated + +--- + +## 四、路由变更 + +### 4.1 新增路由 + +| 路由 | 组件 | 权限 | 说明 | +|------|------|------|------| +| `/purchase` | `PaymentView.vue` | requiresAuth | 替换原 iframe 页面 | +| `/orders` | `UserOrdersView.vue` | requiresAuth | 用户订单列表 | +| `/admin/orders` | `AdminOrdersView.vue` | requiresAdmin | 订单概览(默认 tab) | +| `/admin/orders/list` | 同上组件内 tab | requiresAdmin | 订单列表 | +| `/admin/orders/channels` | 同上组件内 tab | requiresAdmin | 渠道管理 | +| `/admin/orders/plans` | 同上组件内 tab | requiresAdmin | 订阅套餐管理 | +| `/admin/orders/providers` | `AdminProvidersView.vue` | requiresAdmin | 服务商实例管理 | + +### 4.2 路由 meta + +所有支付相关路由需要 meta 字段: + +```typescript +meta: { + requiresAuth: true, + requiresPayment: true, // 新增: 需要 payment_enabled +} +``` + +路由守卫检查:若 `requiresPayment && !payment_enabled`,重定向到 dashboard。 + +--- + +## 五、新增 Vue 组件清单 + +### 5.1 用户侧页面 + +#### 5.1.1 `PaymentView.vue` — 充值/订阅主页面 + +**替换**: `PurchaseSubscriptionView.vue`(iframe) + +**来源**: sub2apipay `PaymentForm.tsx` + `PurchaseFlow.tsx` + `TopUpModal.tsx` + +**功能**: +- 金额输入(自定义 + 快捷按钮) +- 支付方式选择(动态展示) +- 手续费实时计算 +- 余额支付开关 +- 订阅套餐选购(卡片 + 确认弹窗) +- 创建订单后跳转支付流程 + +**子组件**: `PaymentMethodSelector.vue`, `AmountInput.vue`, `FeeDisplay.vue`, `SubscriptionPlanCard.vue`, `SubscriptionConfirmModal.vue` + +**API**: `GET /api/v1/payment/config`, `GET /api/v1/payment/plans`, `POST /api/v1/payment/orders` + +#### 5.1.2 `PaymentQRCodeView.vue` — 二维码支付页 + +**来源**: sub2apipay `PaymentQRCode.tsx` + +**功能**: 二维码显示、倒计时、轮询状态(3s)、支付成功自动跳转 + +**子组件**: `QRCodeDisplay.vue`, `CountdownTimer.vue` + +**API**: `GET /api/v1/payment/orders/:id` + +#### 5.1.3 `StripePaymentView.vue` — Stripe 支付页 + +**来源**: sub2apipay `stripe-popup/page.tsx` + +**功能**: Stripe Payment Element 集成,使用 `clientSecret` 完成支付 + +**依赖**: `@stripe/stripe-js` + +#### 5.1.4 `PaymentResultView.vue` — 支付结果页 + +**功能**: 成功/失败状态展示、订单摘要、跳转按钮 + +#### 5.1.5 `UserOrdersView.vue` — 我的订单 + +**来源**: sub2apipay `OrderTable.tsx` + `MobileOrderList.tsx` + `OrderFilterBar.tsx` + +**功能**: 订单列表(分页、状态筛选、日期范围)、取消/退款操作 + +**子组件**: `OrderStatusBadge.vue`, `OrderFilterBar.vue` + +**API**: `GET /api/v1/payment/orders/my`, `POST .../cancel`, `POST .../refund-request` + +### 5.2 管理员侧页面 + +#### 5.2.1 `AdminOrdersView.vue` — 订单管理(tab 容器) + +页面内 tab 导航:订单概览 | 订单列表 | 渠道管理 | 订阅套餐 + +**订单概览 tab**: +- 统计卡片(今日/总收入、订单数、均价) +- 每日收入趋势图(Chart.js) +- 支付方式分布饼图 +- 充值排行榜 + +**子组件**: `OrderStatsCards.vue`, `DailyRevenueChart.vue`, `PaymentMethodChart.vue`, `TopUsersLeaderboard.vue` + +**API**: `GET /api/v1/admin/payment/dashboard` + +#### 5.2.2 订单列表 tab + +**来源**: sub2apipay `admin/orders/page.tsx` + `admin/OrderTable.tsx` + `admin/OrderDetail.tsx` + `admin/RefundDialog.tsx` + +**功能**: 全量订单搜索/筛选、详情面板、管理操作(取消/重试/退款) + +**子组件**: `AdminOrderTable.vue`, `AdminOrderDetail.vue`, `AdminRefundDialog.vue`, `AdminOrderSearchBar.vue` + +**API**: `GET/POST .../admin/payment/orders`, `.../cancel`, `.../retry`, `.../refund` + +#### 5.2.3 渠道管理 tab + +**来源**: sub2apipay `admin/channels/page.tsx` + `ChannelCard.tsx` + +**功能**: 渠道 CRUD(名称、关联 Group、费率、描述、启/禁用) + +**API**: `GET/POST/PUT/DELETE /api/v1/admin/payment/channels` + +#### 5.2.4 订阅套餐 tab + +**来源**: sub2apipay `admin/subscriptions/page.tsx` + +**功能**: 套餐 CRUD(名称、价格、有效期、分组绑定、上架状态) + +**API**: `GET/POST/PUT/DELETE /api/v1/admin/payment/plans` + +#### 5.2.5 `AdminProvidersView.vue` — 服务商实例管理 + +**来源**: sub2apipay `admin/payment-config/page.tsx`(1479 行,最大单组件) + +**功能**: 服务商实例 CRUD,动态配置表单(EasyPay/Alipay/Wxpay/Stripe),限额配置,退款开关 + +**路由**: `/admin/orders/providers`(从系统设置 payment tab "管理实例"按钮跳转) + +**子组件**: `ProviderInstanceForm.vue`, `ProviderInstanceCard.vue` + +**API**: `GET/POST/PUT/DELETE /api/v1/admin/payment/providers` + +### 5.3 共享组件 + +| 组件 | 用途 | +|------|------| +| `PaymentMethodSelector.vue` | 支付方式选择 | +| `AmountInput.vue` | 金额输入(含快捷按钮) | +| `FeeDisplay.vue` | 手续费展示 | +| `QRCodeDisplay.vue` | 二维码渲染 | +| `CountdownTimer.vue` | 倒计时 | +| `OrderStatusBadge.vue` | 订单状态标签 | +| `OrderFilterBar.vue` | 订单筛选栏 | +| `SubscriptionPlanCard.vue` | 套餐卡片 | +| `SubscriptionConfirmModal.vue` | 套餐确认弹窗 | + +--- + +## 六、Store 变更 + +### 6.1 `appStore` 变更 + +**publicSettings 字段变更**: +```typescript +// deprecated: +purchase_subscription_enabled: boolean +purchase_subscription_url: string + +// 新增: +payment_enabled: boolean // 充值/订阅功能总开关 +``` + +### 6.2 新增 `paymentStore` + +```typescript +// src/stores/payment.ts +defineStore('payment', () => { + const config = ref(null) + const currentOrder = ref(null) + const plans = ref([]) + + async function fetchConfig(): Promise + async function fetchPlans(): Promise + async function createOrder(params): Promise + async function pollOrderStatus(orderId: string): Promise +}) +``` + +### 6.3 `adminSettingsStore` 变更 + +新增: `paymentEnabled` — 控制管理侧"订单管理"菜单可见性。 + +--- + +## 七、API 模块新增 + +### 7.1 用户 API (`src/api/payment.ts`) + +```typescript +export const paymentAPI = { + getConfig(): Promise + getPlans(): Promise + createOrder(params): Promise + getOrder(orderId): Promise + getMyOrders(params): Promise> + cancelOrder(orderId): Promise + requestRefund(orderId, reason): Promise + getLimits(): Promise +} +``` + +### 7.2 管理 API (`src/api/admin/payment.ts`) + +```typescript +export const adminPaymentAPI = { + // 仪表盘 + getDashboard(days?): Promise + // 订单 + getOrders(params): Promise> + getOrder(orderId): Promise + cancelOrder(orderId): Promise + retryRecharge(orderId): Promise + refundOrder(orderId, params): Promise + // 渠道 + getChannels(): Promise + createChannel(data): Promise + updateChannel(id, data): Promise + deleteChannel(id): Promise + // 订阅套餐 + getPlans(): Promise + createPlan(data): Promise + updatePlan(id, data): Promise + deletePlan(id): Promise + // 服务商实例 + getProviders(): Promise + createProvider(data): Promise + updateProvider(id, data): Promise + deleteProvider(id): Promise +} +``` + +--- + +## 八、i18n 变更 + +### 8.1 新增 `payment` 命名空间 + +```typescript +payment: { + // 充值页面 + title: '充值/订阅', // 'Recharge / Subscription' + amountLabel: '充值金额', + quickAmounts: '快捷金额', + customAmount: '自定义金额', + paymentMethod: '支付方式', + fee: '手续费', + actualPay: '实付金额', + createOrder: '确认支付', + + methods: { + alipay: '支付宝', + wxpay: '微信支付', + stripe: 'Stripe', + alipay_direct: '支付宝(直连)', + wxpay_direct: '微信支付(直连)', + }, + + status: { + pending: '待支付', + paid: '已支付', + recharging: '充值中', + completed: '已完成', + expired: '已过期', + cancelled: '已取消', + failed: '失败', + refund_requested: '退款申请中', + refunding: '退款中', + refunded: '已退款', + partially_refunded: '部分退款', + refund_failed: '退款失败', + }, + + qr: { + scanToPay: '请扫码支付', + expiresIn: '剩余支付时间', + expired: '订单已过期', + }, + + orders: { + title: '我的订单', + empty: '暂无订单', + orderId: '订单号', + amount: '金额', + payAmount: '实付', + status: '状态', + paymentMethod: '支付方式', + createdAt: '创建时间', + cancel: '取消订单', + requestRefund: '申请退款', + }, + + result: { + success: '支付成功', + failed: '支付失败', + backToRecharge: '返回充值', + viewOrders: '查看订单', + }, +} +``` + +### 8.2 修改的 i18n 键 + +```typescript +nav: { + myOrders: '我的订单', // 'My Orders' + orderManagement: '订单管理', // 'Order Management' +} + +admin.settings.tabs: { + payment: '充值/订阅', // 'Recharge / Subscription' +} + +admin.settings.payment: { + title: '充值/订阅功能', + description: '配置在线支付充值和订阅购买功能', + enabled: '启用充值/订阅', + enabledHint: '开启后用户可通过在线支付充值余额或购买订阅', + minAmount: '最低充值金额', + maxAmount: '最高充值金额', + dailyLimit: '每日充值限额', + maxPendingOrders: '最大待支付订单数', + orderTimeout: '订单超时时间(分钟)', + balancePaymentDisabled: '禁用余额支付', + enabledPaymentTypes: '启用的支付方式', + manageProviders: '管理服务商实例', + helpImageUrl: '帮助图片 URL', + helpText: '帮助文字', +} +``` + +### 8.3 Deprecated i18n 键 + +保留但不再使用:`admin.settings.purchase.*`, `purchase.*` + +--- + +## 九、文件变更清单 + +### 9.1 修改的现有文件 + +| 文件 | 变更 | +|------|------| +| `src/components/layout/AppSidebar.vue` | 新增菜单项,条件改为 `payment_enabled` | +| `src/router/index.ts` | 新增路由,修改 `/purchase` 组件 | +| `src/views/admin/SettingsView.vue` | 新增 `payment` tab,移除旧 purchase 配置 | +| `src/stores/app.ts` | publicSettings 新增 `payment_enabled` | +| `src/stores/adminSettings.ts` | 新增 `paymentEnabled` | +| `src/stores/index.ts` | 导出新 store | +| `src/i18n/locales/en.ts` | 新增 payment 命名空间 | +| `src/i18n/locales/zh.ts` | 新增 payment 命名空间 | +| `src/api/index.ts` | 导出新 API 模块 | +| `src/types/index.ts` | 新增 payment 类型 | + +### 9.2 新增文件 + +**视图 (10 个)**: +- `src/views/user/PaymentView.vue` +- `src/views/user/PaymentQRCodeView.vue` +- `src/views/user/StripePaymentView.vue` +- `src/views/user/PaymentResultView.vue` +- `src/views/user/UserOrdersView.vue` +- `src/views/admin/orders/AdminOrdersView.vue` +- `src/views/admin/orders/AdminOrderListView.vue` +- `src/views/admin/orders/AdminOrderChannelsView.vue` +- `src/views/admin/orders/AdminOrderPlansView.vue` +- `src/views/admin/orders/AdminProvidersView.vue` + +**组件 (19 个)**: +- `src/components/payment/PaymentMethodSelector.vue` +- `src/components/payment/AmountInput.vue` +- `src/components/payment/FeeDisplay.vue` +- `src/components/payment/QRCodeDisplay.vue` +- `src/components/payment/CountdownTimer.vue` +- `src/components/payment/OrderStatusBadge.vue` +- `src/components/payment/OrderFilterBar.vue` +- `src/components/payment/SubscriptionPlanCard.vue` +- `src/components/payment/SubscriptionConfirmModal.vue` +- `src/components/admin/payment/OrderStatsCards.vue` +- `src/components/admin/payment/DailyRevenueChart.vue` +- `src/components/admin/payment/PaymentMethodChart.vue` +- `src/components/admin/payment/TopUsersLeaderboard.vue` +- `src/components/admin/payment/AdminOrderTable.vue` +- `src/components/admin/payment/AdminOrderDetail.vue` +- `src/components/admin/payment/AdminRefundDialog.vue` +- `src/components/admin/payment/AdminOrderSearchBar.vue` +- `src/components/admin/payment/ProviderInstanceForm.vue` +- `src/components/admin/payment/ProviderInstanceCard.vue` + +**API / Store / Types (4 个)**: +- `src/api/payment.ts` +- `src/api/admin/payment.ts` +- `src/stores/payment.ts` +- `src/types/payment.ts` + +### 9.3 删除的文件 + +| 文件 | 说明 | +|------|------| +| `src/views/user/PurchaseSubscriptionView.vue` | 替换为 `PaymentView.vue` | +| `src/utils/embedded-url.ts` | 不再需要 iframe URL 构建 | + +### 9.4 新增依赖 + +| 包 | 用途 | +|----|------| +| `@stripe/stripe-js` | Stripe Payment Element | +| `qrcode` | 二维码渲染(已有此依赖) | + +--- + +## 十、后端 Setting 表新增键(前端消费) + +| Key | 类型 | 默认值 | 说明 | +|-----|------|--------|------| +| `payment_enabled` | bool | `false` | 总开关 | +| `payment_min_amount` | number | `1` | 最低充值额 | +| `payment_max_amount` | number | `10000` | 最高充值额 | +| `payment_daily_limit` | number | `50000` | 日限额 | +| `payment_max_pending_orders` | number | `3` | 最大待支付数 | +| `payment_order_timeout_minutes` | number | `30` | 订单超时 | +| `payment_balance_disabled` | bool | `false` | 禁用余额支付 | +| `payment_enabled_types` | string | `""` | 支付方式(逗号分隔) | +| `payment_help_image_url` | string | `""` | 帮助图片 | +| `payment_help_text` | string | `""` | 帮助文字 | + +--- + +## 十一、实施顺序 + +### Phase 1: 基础设施 +1. TypeScript 类型定义 (`types/payment.ts`) +2. API 模块 (`api/payment.ts`, `api/admin/payment.ts`) +3. Store (`stores/payment.ts`) +4. 修改 `stores/app.ts` + `stores/adminSettings.ts` +5. 修改 `router/index.ts` — 新增路由 +6. 修改 `AppSidebar.vue` — 新增菜单项 +7. 新增 i18n 文本 + +### Phase 2: 用户侧页面 +1. `PaymentView.vue` + 子组件 +2. `PaymentQRCodeView.vue` + QR 组件 +3. `StripePaymentView.vue` +4. `PaymentResultView.vue` +5. `UserOrdersView.vue` + 订单组件 + +### Phase 3: 管理侧页面 +1. `AdminOrdersView.vue`(tab 容器 + 订单概览) +2. 订单列表 tab + 表格/详情/退款 +3. 渠道管理 tab +4. 订阅套餐 tab +5. `AdminProvidersView.vue`(最复杂) + +### Phase 4: 系统设置集成 +1. `SettingsView.vue` — 新增 `payment` tab +2. 移除 `general` tab 旧 purchase 配置 +3. 旧版兼容迁移逻辑 + +--- + +## 附录 A: sub2apipay → sub2api 组件映射 + +| sub2apipay (React) | 行数 | sub2api (Vue3) | 说明 | +|---------------------|------|----------------|------| +| `PaymentForm.tsx` | ~400 | `PaymentView.vue` + 子组件 | 拆分为细粒度组件 | +| `PaymentQRCode.tsx` | ~300 | `PaymentQRCodeView.vue` | | +| `PurchaseFlow.tsx` | ~350 | 融入 `PaymentView.vue` | | +| `SubscriptionConfirm.tsx` | ~200 | `SubscriptionConfirmModal.vue` | | +| `SubscriptionPlanCard.tsx` | ~150 | `SubscriptionPlanCard.vue` | | +| `TopUpModal.tsx` | ~300 | 融入 `PaymentView.vue` | | +| `OrderTable.tsx` | ~250 | 复用 sub2api DataTable | | +| `MobileOrderList.tsx` | ~200 | 响应式设计融入 View | | +| `OrderFilterBar.tsx` | ~150 | `OrderFilterBar.vue` | | +| `OrderStatus.tsx` | ~100 | `OrderStatusBadge.vue` | | +| `admin/DashboardStats.tsx` | ~150 | `OrderStatsCards.vue` | | +| `admin/DailyChart.tsx` | ~200 | `DailyRevenueChart.vue` | | +| `admin/PaymentMethodChart.tsx` | ~150 | `PaymentMethodChart.vue` | | +| `admin/Leaderboard.tsx` | ~150 | `TopUsersLeaderboard.vue` | | +| `admin/OrderTable.tsx` | ~300 | `AdminOrderTable.vue` | | +| `admin/OrderDetail.tsx` | ~250 | `AdminOrderDetail.vue` | | +| `admin/RefundDialog.tsx` | ~200 | `AdminRefundDialog.vue` | | +| `admin/payment-config (page.tsx)` | ~1479 | 拆分为 View + Form + Card | | + +## 附录 B: 关键设计决策 + +### B.1 为什么不保留 iframe + +| 维度 | iframe | 原生集成 | +|------|--------|---------| +| 用户体验 | 两套 UI,主题同步延迟 | 统一 UI | +| 认证 | URL 传 token,泄露风险 | JWT 自动携带 | +| 部署 | 需独立部署 + 域名 | 单一部署 | +| 维护 | 两个项目两套技术栈 | 一个项目 | +| 性能 | iframe 加载开销 | 无额外开销 | +| CSP | X-Frame-Options 兼容问题 | 无此问题 | + +### B.2 "订单管理"作为一级菜单 + +- 订单是高频管理操作,需快速访问 +- 包含 4 个子功能,信息密度高 +- 遵循 sub2api 现有模式:业务操作独立菜单 + +### B.3 `payment_enabled` 总开关 + +- 所有支付菜单和路由受此开关控制 +- 关闭时:侧边栏不显示、路由守卫重定向、后端 API 同步校验 +- 零配置时不影响不使用支付功能的用户 diff --git a/docs/PAYMENT_IMPLEMENTATION_ROADMAP.md b/docs/PAYMENT_IMPLEMENTATION_ROADMAP.md new file mode 100644 index 0000000000..25eedbd7f8 --- /dev/null +++ b/docs/PAYMENT_IMPLEMENTATION_ROADMAP.md @@ -0,0 +1,276 @@ +# 支付系统实施路线图 + +> 基于前端计划 + 后端计划的完整实施路线图 +> +> 分支: `feature/payment` @ `touwaeriol/sub2api` + +--- + +## Phase 概览 + +``` +Phase 1: 数据库 & Schema ← 无依赖,最先开始 +Phase 2: Go 后端核心 ← 依赖 Phase 1 +Phase 3: Go 后端 API ← 依赖 Phase 2 +Phase 4: 前端基础设施 ← 可与 Phase 2 并行 +Phase 5: 前端用户页面 ← 依赖 Phase 3 + 4 +Phase 6: 前端管理页面 ← 依赖 Phase 3 + 4 +``` + +--- + +## Phase 1: 数据库 & Schema + +### 任务列表 + +| # | 任务 | 文件 | 说明 | +|---|------|------|------| +| 1.1 | PaymentOrder schema | ent/schema/payment_order.go | 订单表,12种状态 | +| 1.2 | PaymentAuditLog schema | ent/schema/payment_audit_log.go | 审计日志 | +| 1.3 | PaymentChannel schema | ent/schema/payment_channel.go | 展示渠道 | +| 1.4 | SubscriptionPlan schema | ent/schema/subscription_plan.go | 订阅套餐 | +| 1.5 | PaymentProviderInstance schema | ent/schema/payment_provider_instance.go | 服务商实例 | +| 1.6 | SQL migration: orders | migrations/090_payment_orders.sql | | +| 1.7 | SQL migration: audit_logs | migrations/091_payment_audit_logs.sql | | +| 1.8 | SQL migration: channels | migrations/092_payment_channels.sql | | +| 1.9 | SQL migration: plans | migrations/093_subscription_plans.sql | | +| 1.10 | SQL migration: instances | migrations/094_payment_provider_instances.sql | | +| 1.11 | Ent generate | `go generate ./ent` | 生成 CRUD 代码 | + +**验收**: `go build ./...` 通过,Ent 生成代码无报错 + +--- + +## Phase 2: Go 后端核心 + +### 2A: 支付基础设施(可并行) + +| # | 任务 | 文件 | 说明 | +|---|------|------|------| +| 2.1 | 类型 & 接口定义 | internal/payment/types.go | Provider 接口, 请求/响应类型 | +| 2.2 | Provider 注册表 | internal/payment/registry.go | 动态注册/查找 | +| 2.3 | 手续费计算 | internal/payment/fee.go | shopspring/decimal, ROUND_UP | +| 2.4 | AES 加解密 | internal/payment/crypto.go | 实例配置加密 | +| 2.5 | 负载均衡 | internal/payment/load_balancer.go | round-robin / least-amount | +| 2.6 | Provider 工厂 | internal/payment/provider_factory.go | 根据实例配置创建 Provider | + +### 2B: Provider 实现(可并行) + +| # | 任务 | 文件 | SDK | +|---|------|------|-----| +| 2.7 | EasyPay | internal/payment/provider/easypay.go | net/http + crypto/md5 | +| 2.8 | Alipay | internal/payment/provider/alipay.go | smartwalle/alipay/v3 | +| 2.9 | Wxpay | internal/payment/provider/wxpay.go | wechatpay-apiv3/wechatpay-go | +| 2.10 | Stripe | internal/payment/provider/stripe.go | stripe/stripe-go/v82 | + +### 2C: Service 层(依赖 2A + 2B) + +| # | 任务 | 文件 | 说明 | +|---|------|------|------| +| 2.11 | 配置服务 | internal/service/payment_config_service.go | 系统配置+实例+渠道+套餐 CRUD | +| 2.12 | 订单服务-创建 | internal/service/payment_service.go | 创建订单、手续费、限额校验 | +| 2.13 | 订单服务-支付确认 | 同上 | Webhook 处理、状态流转 | +| 2.14 | 订单服务-履约 | 同上 | 余额充值(RedeemService)、订阅激活 | +| 2.15 | 订单服务-退款 | 同上 | prepare/execute/rollback 三阶段 | +| 2.16 | 订单服务-超时 | 同上 | 定时过期 + 关单 | +| 2.17 | 订单服务-统计 | 同上 | Dashboard 聚合查询 | +| 2.18 | Wire DI | internal/payment/wire.go | Provider Set | + +**验收**: 单元测试通过,`go build ./...` 通过 + +### 新增 Go 依赖 + +```bash +go get github.com/stripe/stripe-go/v82 +go get github.com/smartwalle/alipay/v3 +go get github.com/wechatpay-apiv3/wechatpay-go +go get github.com/shopspring/decimal +``` + +--- + +## Phase 3: Go 后端 API + +### 3A: Handler 层 + +| # | 任务 | 文件 | 端点数 | +|---|------|------|--------| +| 3.1 | 用户 Handler | internal/handler/payment_handler.go | 9 | +| 3.2 | Webhook Handler | internal/handler/payment_webhook_handler.go | 4 | +| 3.3 | 管理 Handler | internal/handler/admin/payment_handler.go | 18 | + +### 3B: 路由 & 集成 + +| # | 任务 | 文件 | 说明 | +|---|------|------|------| +| 3.4 | 路由注册 | internal/server/routes/payment.go | 新路由文件 | +| 3.5 | Router 集成 | internal/server/router.go | registerRoutes 中调用 | +| 3.6 | Handlers 结构体 | internal/handler/handlers.go | 添加 Payment 字段 | +| 3.7 | Wire 更新 | cmd/server/wire.go | 注入支付依赖 | +| 3.8 | Settings API 扩展 | internal/handler/admin/setting_handler.go | payment_enabled 等配置 | + +**验收**: API 可调通(curl/Postman),Webhook 端点可接收请求 + +--- + +## Phase 4: 前端基础设施 + +可与 Phase 2 并行开始。 + +| # | 任务 | 文件 | 说明 | +|---|------|------|------| +| 4.1 | TypeScript 类型 | frontend/src/types/payment.ts | Order, Plan, Channel 等类型 | +| 4.2 | 用户 API 模块 | frontend/src/api/payment.ts | 9 个 API 方法 | +| 4.3 | 管理 API 模块 | frontend/src/api/admin/payment.ts | 18 个 API 方法 | +| 4.4 | API 导出 | frontend/src/api/index.ts | 导出新模块 | +| 4.5 | Payment Store | frontend/src/stores/payment.ts | 配置/订单/套餐状态 | +| 4.6 | App Store 修改 | frontend/src/stores/app.ts | 新增 payment_enabled | +| 4.7 | Admin Store 修改 | frontend/src/stores/adminSettings.ts | 新增 paymentEnabled | +| 4.8 | Router 新增路由 | frontend/src/router/index.ts | 7 个新路由 + meta | +| 4.9 | 路由守卫 | frontend/src/router/index.ts | requiresPayment 检查 | +| 4.10 | Sidebar 修改 | frontend/src/components/layout/AppSidebar.vue | 新增菜单项 | +| 4.11 | i18n 英文 | frontend/src/i18n/locales/en.ts | payment 命名空间 | +| 4.12 | i18n 中文 | frontend/src/i18n/locales/zh.ts | payment 命名空间 | + +**新增前端依赖**: +```bash +cd frontend && pnpm add @stripe/stripe-js +``` + +**验收**: `pnpm typecheck` 通过,菜单可见性正确 + +--- + +## Phase 5: 前端用户页面 + +依赖 Phase 3 (API) + Phase 4 (基础设施)。 + +| # | 任务 | 文件 | 说明 | +|---|------|------|------| +| 5.1 | 支付方式选择器 | components/payment/PaymentMethodSelector.vue | 共享组件 | +| 5.2 | 金额输入 | components/payment/AmountInput.vue | 快捷按钮+自定义 | +| 5.3 | 手续费展示 | components/payment/FeeDisplay.vue | 实时计算 | +| 5.4 | 套餐卡片 | components/payment/SubscriptionPlanCard.vue | | +| 5.5 | 套餐确认弹窗 | components/payment/SubscriptionConfirmModal.vue | | +| 5.6 | **充值/订阅主页** | views/user/PaymentView.vue | 替换 iframe,核心页面 | +| 5.7 | QR码展示 | components/payment/QRCodeDisplay.vue | qrcode 库 | +| 5.8 | 倒计时 | components/payment/CountdownTimer.vue | | +| 5.9 | **二维码支付页** | views/user/PaymentQRCodeView.vue | 轮询+倒计时 | +| 5.10 | **Stripe 支付页** | views/user/StripePaymentView.vue | Payment Element | +| 5.11 | **支付结果页** | views/user/PaymentResultView.vue | 成功/失败展示 | +| 5.12 | 订单状态标签 | components/payment/OrderStatusBadge.vue | 彩色标签 | +| 5.13 | 订单筛选栏 | components/payment/OrderFilterBar.vue | | +| 5.14 | **我的订单页** | views/user/UserOrdersView.vue | 列表+筛选+操作 | +| 5.15 | 删除旧文件 | PurchaseSubscriptionView.vue, embedded-url.ts | | + +**验收**: 用户可完成充值流程(创建订单→扫码/Stripe→支付成功→余额增加) + +--- + +## Phase 6: 前端管理页面 + +可与 Phase 5 并行。 + +| # | 任务 | 文件 | 说明 | +|---|------|------|------| +| 6.1 | 统计卡片 | components/admin/payment/OrderStatsCards.vue | | +| 6.2 | 日收入图表 | components/admin/payment/DailyRevenueChart.vue | Chart.js | +| 6.3 | 支付分布图 | components/admin/payment/PaymentMethodChart.vue | | +| 6.4 | 排行榜 | components/admin/payment/TopUsersLeaderboard.vue | | +| 6.5 | **订单管理页(tab容器)** | views/admin/orders/AdminOrdersView.vue | 4个tab | +| 6.6 | 管理订单表格 | components/admin/payment/AdminOrderTable.vue | DataTable | +| 6.7 | 订单详情 | components/admin/payment/AdminOrderDetail.vue | | +| 6.8 | 退款对话框 | components/admin/payment/AdminRefundDialog.vue | | +| 6.9 | 订单搜索栏 | components/admin/payment/AdminOrderSearchBar.vue | | +| 6.10 | **订单列表tab** | 融入 AdminOrdersView | | +| 6.11 | **渠道管理tab** | views/admin/orders/AdminOrderChannelsView.vue | | +| 6.12 | **订阅套餐tab** | views/admin/orders/AdminOrderPlansView.vue | | +| 6.13 | 服务商实例表单 | components/admin/payment/ProviderInstanceForm.vue | | +| 6.14 | 服务商实例卡片 | components/admin/payment/ProviderInstanceCard.vue | | +| 6.15 | **服务商管理页** | views/admin/orders/AdminProvidersView.vue | | +| 6.16 | **Settings payment tab** | 修改 SettingsView.vue | 新增tab+移除旧配置 | +| 6.17 | 旧版兼容迁移 | Go migration code | purchase_url→自定义菜单 | + +**验收**: 管理员可完成全流程(配置支付→管理订单→处理退款) + +--- + +## 依赖关系图 + +``` +Phase 1 (DB) + │ + ▼ +Phase 2 (Go Core) ──────┐ + │ │ + ▼ │ +Phase 3 (Go API) ◄──────┤ + │ │ + ▼ ▼ +Phase 5 (User UI) ◄── Phase 4 (FE Infra) + │ +Phase 6 (Admin UI) ◄────┘ + +可并行: +- Phase 2A + 2B (基础设施 + Provider 实现) +- Phase 4 可与 Phase 2 同时开始 +- Phase 5 + Phase 6 可并行 +``` + +--- + +## 测试策略 + +### 后端单元测试 + +| 测试文件 | 覆盖 | +|---------|------| +| internal/payment/fee_test.go | 手续费计算精度 | +| internal/payment/registry_test.go | 注册/查找 | +| internal/payment/load_balancer_test.go | 实例选择策略 | +| internal/payment/crypto_test.go | 加解密正确性 | +| internal/payment/provider/easypay_test.go | 签名验证 | +| internal/service/payment_service_test.go | 订单状态流转 | +| internal/service/payment_config_service_test.go | 配置 CRUD | +| internal/handler/payment_handler_test.go | API 请求/响应 | + +### 后端集成测试 + +| 测试 | 覆盖 | +|------|------| +| 订单创建→支付→履约 | 完整流程 | +| 退款三阶段 | prepare→execute→rollback | +| Webhook 验签 | 各 Provider 签名验证 | + +### 前端组件测试 + +| 测试 | 覆盖 | +|------|------| +| PaymentMethodSelector | 选择/禁用/限额展示 | +| AmountInput | 金额验证/精度 | +| OrderStatusBadge | 状态→颜色映射 | +| PaymentView | 创建订单流程 | + +--- + +## 迁移兼容 + +### 滚动部署 3 阶段 + +1. **部署后端** — 新 API 端点上线,但 `payment_enabled=false`,不影响现有功能 +2. **部署前端** — 新页面/组件上线,但菜单隐藏(因为 `payment_enabled=false`) +3. **管理员开启** — 在设置中启用 `payment_enabled`,配置支付服务商,功能生效 + +### purchase_subscription_url 兼容 + +Go 迁移代码在启动时检查: +```go +if url := settingService.Get("purchase_subscription_url"); url != "" { + // 自动创建 custom_menu_item 保留旧 URL + // 标记 purchase_subscription_url 为 deprecated +} +``` + +### 数据库迁移顺序 + +迁移 090-094 仅创建新表,不修改现有表,零风险。 diff --git a/frontend/src/api/admin/index.ts b/frontend/src/api/admin/index.ts index da1e3cfa8f..7259736543 100644 --- a/frontend/src/api/admin/index.ts +++ b/frontend/src/api/admin/index.ts @@ -26,6 +26,7 @@ import scheduledTestsAPI from './scheduledTests' import backupAPI from './backup' import tlsFingerprintProfileAPI from './tlsFingerprintProfile' import channelsAPI from './channels' +import adminPaymentAPI from './payment' /** * Unified admin API object for convenient access @@ -53,7 +54,8 @@ export const adminAPI = { scheduledTests: scheduledTestsAPI, backup: backupAPI, tlsFingerprintProfiles: tlsFingerprintProfileAPI, - channels: channelsAPI + channels: channelsAPI, + payment: adminPaymentAPI } export { @@ -79,7 +81,8 @@ export { scheduledTestsAPI, backupAPI, tlsFingerprintProfileAPI, - channelsAPI + channelsAPI, + adminPaymentAPI } export default adminAPI diff --git a/frontend/src/api/admin/payment.ts b/frontend/src/api/admin/payment.ts new file mode 100644 index 0000000000..06434cb784 --- /dev/null +++ b/frontend/src/api/admin/payment.ts @@ -0,0 +1,130 @@ +/** + * Admin Payment API endpoints + * Handles payment management operations for administrators + */ + +import { apiClient } from '../client' +import type { + DashboardStats, + PaymentOrder, + PaymentChannel, + SubscriptionPlan, + ProviderInstance +} from '@/types/payment' +import type { BasePaginationResponse } from '@/types' + +export const adminPaymentAPI = { + // ==================== Dashboard ==================== + + /** Get payment dashboard statistics */ + getDashboard(days?: number) { + return apiClient.get('/admin/payment/dashboard', { + params: days ? { days } : undefined + }) + }, + + // ==================== Orders ==================== + + /** Get all orders (paginated, with filters) */ + getOrders(params?: { + page?: number + page_size?: number + status?: string + payment_type?: string + user_id?: number + keyword?: string + start_date?: string + end_date?: string + order_type?: string + }) { + return apiClient.get>('/admin/payment/orders', { params }) + }, + + /** Get a specific order by ID */ + getOrder(id: number) { + return apiClient.get(`/admin/payment/orders/${id}`) + }, + + /** Cancel an order (admin) */ + cancelOrder(id: number) { + return apiClient.post(`/admin/payment/orders/${id}/cancel`) + }, + + /** Retry recharge for a failed order */ + retryRecharge(id: number) { + return apiClient.post(`/admin/payment/orders/${id}/retry`) + }, + + /** Process a refund */ + refundOrder(id: number, data: { amount: number; reason: string; deduct_balance?: boolean }) { + return apiClient.post(`/admin/payment/orders/${id}/refund`, data) + }, + + // ==================== Channels ==================== + + /** Get all payment channels */ + getChannels() { + return apiClient.get('/admin/payment/channels') + }, + + /** Create a payment channel */ + createChannel(data: Partial) { + return apiClient.post('/admin/payment/channels', data) + }, + + /** Update a payment channel */ + updateChannel(id: number, data: Partial) { + return apiClient.put(`/admin/payment/channels/${id}`, data) + }, + + /** Delete a payment channel */ + deleteChannel(id: number) { + return apiClient.delete(`/admin/payment/channels/${id}`) + }, + + // ==================== Subscription Plans ==================== + + /** Get all subscription plans */ + getPlans() { + return apiClient.get('/admin/payment/plans') + }, + + /** Create a subscription plan */ + createPlan(data: Partial) { + return apiClient.post('/admin/payment/plans', data) + }, + + /** Update a subscription plan */ + updatePlan(id: number, data: Partial) { + return apiClient.put(`/admin/payment/plans/${id}`, data) + }, + + /** Delete a subscription plan */ + deletePlan(id: number) { + return apiClient.delete(`/admin/payment/plans/${id}`) + }, + + // ==================== Provider Instances ==================== + + /** Get all provider instances */ + getProviders() { + return apiClient.get('/admin/payment/providers') + }, + + /** Create a provider instance */ + createProvider(data: Partial) { + return apiClient.post('/admin/payment/providers', data) + }, + + /** Update a provider instance */ + updateProvider(id: number, data: Partial) { + return apiClient.put(`/admin/payment/providers/${id}`, data) + }, + + /** Delete a provider instance */ + deleteProvider(id: number) { + return apiClient.delete(`/admin/payment/providers/${id}`) + } +} + +export default adminPaymentAPI diff --git a/frontend/src/api/admin/settings.ts b/frontend/src/api/admin/settings.ts index 8f9284b70e..3efc732070 100644 --- a/frontend/src/api/admin/settings.ts +++ b/frontend/src/api/admin/settings.ts @@ -40,6 +40,8 @@ export interface SystemSettings { hide_ccs_import_button: boolean purchase_subscription_enabled: boolean purchase_subscription_url: string + payment_enabled: boolean + sora_client_enabled: boolean backend_mode_enabled: boolean custom_menu_items: CustomMenuItem[] custom_endpoints: CustomEndpoint[] diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts index 070ce64850..6b3ef17493 100644 --- a/frontend/src/api/index.ts +++ b/frontend/src/api/index.ts @@ -14,6 +14,7 @@ export { keysAPI } from './keys' export { usageAPI } from './usage' export { userAPI } from './user' export { redeemAPI, type RedeemHistoryItem } from './redeem' +export { paymentAPI } from './payment' export { userGroupsAPI } from './groups' export { totpAPI } from './totp' export { default as announcementsAPI } from './announcements' diff --git a/frontend/src/api/payment.ts b/frontend/src/api/payment.ts new file mode 100644 index 0000000000..46492a07c4 --- /dev/null +++ b/frontend/src/api/payment.ts @@ -0,0 +1,63 @@ +/** + * User Payment API endpoints + * Handles payment operations for regular users + */ + +import { apiClient } from './client' +import type { + PaymentConfig, + SubscriptionPlan, + PaymentChannel, + MethodLimit, + CreateOrderRequest, + CreateOrderResult, + PaymentOrder +} from '@/types/payment' +import type { BasePaginationResponse } from '@/types' + +export const paymentAPI = { + /** Get payment configuration (enabled types, limits, etc.) */ + getConfig() { + return apiClient.get('/payment/config') + }, + + /** Get available subscription plans */ + getPlans() { + return apiClient.get('/payment/plans') + }, + + /** Get available payment channels */ + getChannels() { + return apiClient.get('/payment/channels') + }, + + /** Get payment method limits and fee rates */ + getLimits() { + return apiClient.get>('/payment/limits') + }, + + /** Create a new payment order */ + createOrder(data: CreateOrderRequest) { + return apiClient.post('/payment/orders', data) + }, + + /** Get current user's orders */ + getMyOrders(params?: { page?: number; page_size?: number; status?: string }) { + return apiClient.get>('/payment/orders/my', { params }) + }, + + /** Get a specific order by ID */ + getOrder(id: number) { + return apiClient.get(`/payment/orders/${id}`) + }, + + /** Cancel a pending order */ + cancelOrder(id: number) { + return apiClient.post(`/payment/orders/${id}/cancel`) + }, + + /** Request a refund for a completed order */ + requestRefund(id: number, data: { reason: string }) { + return apiClient.post(`/payment/orders/${id}/refund-request`, data) + } +} diff --git a/frontend/src/components/admin/payment/AdminOrderDetail.vue b/frontend/src/components/admin/payment/AdminOrderDetail.vue new file mode 100644 index 0000000000..5c2e5ae7f4 --- /dev/null +++ b/frontend/src/components/admin/payment/AdminOrderDetail.vue @@ -0,0 +1,149 @@ + + + diff --git a/frontend/src/components/admin/payment/AdminOrderTable.vue b/frontend/src/components/admin/payment/AdminOrderTable.vue new file mode 100644 index 0000000000..17423d170d --- /dev/null +++ b/frontend/src/components/admin/payment/AdminOrderTable.vue @@ -0,0 +1,235 @@ + + + diff --git a/frontend/src/components/admin/payment/AdminRefundDialog.vue b/frontend/src/components/admin/payment/AdminRefundDialog.vue new file mode 100644 index 0000000000..286f81d7b6 --- /dev/null +++ b/frontend/src/components/admin/payment/AdminRefundDialog.vue @@ -0,0 +1,131 @@ + + + diff --git a/frontend/src/components/admin/payment/DailyRevenueChart.vue b/frontend/src/components/admin/payment/DailyRevenueChart.vue new file mode 100644 index 0000000000..77583da17b --- /dev/null +++ b/frontend/src/components/admin/payment/DailyRevenueChart.vue @@ -0,0 +1,99 @@ + + + diff --git a/frontend/src/components/admin/payment/OrderStatsCards.vue b/frontend/src/components/admin/payment/OrderStatsCards.vue new file mode 100644 index 0000000000..52faf38263 --- /dev/null +++ b/frontend/src/components/admin/payment/OrderStatsCards.vue @@ -0,0 +1,77 @@ + + + diff --git a/frontend/src/components/admin/payment/PaymentMethodChart.vue b/frontend/src/components/admin/payment/PaymentMethodChart.vue new file mode 100644 index 0000000000..dd6909e95b --- /dev/null +++ b/frontend/src/components/admin/payment/PaymentMethodChart.vue @@ -0,0 +1,75 @@ + + + diff --git a/frontend/src/components/admin/payment/TopUsersLeaderboard.vue b/frontend/src/components/admin/payment/TopUsersLeaderboard.vue new file mode 100644 index 0000000000..1c85fcf161 --- /dev/null +++ b/frontend/src/components/admin/payment/TopUsersLeaderboard.vue @@ -0,0 +1,52 @@ + + + diff --git a/frontend/src/components/layout/AppSidebar.vue b/frontend/src/components/layout/AppSidebar.vue index 09b83f6f25..00b085acb7 100644 --- a/frontend/src/components/layout/AppSidebar.vue +++ b/frontend/src/components/layout/AppSidebar.vue @@ -467,6 +467,66 @@ const ChevronDoubleLeftIcon = { ) } +const SoraIcon = { + render: () => + h( + 'svg', + { fill: 'none', viewBox: '0 0 24 24', stroke: 'currentColor', 'stroke-width': '1.5' }, + [ + h('path', { + 'stroke-linecap': 'round', + 'stroke-linejoin': 'round', + d: 'M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09z' + }) + ] + ) +} + +const ReceiptIcon = { + render: () => + h( + 'svg', + { fill: 'none', viewBox: '0 0 24 24', stroke: 'currentColor', 'stroke-width': '1.5' }, + [ + h('path', { + 'stroke-linecap': 'round', + 'stroke-linejoin': 'round', + d: 'M9 14.25l6-6m4.5-3.493V21.75l-3.75-1.5-3.75 1.5-3.75-1.5-3.75 1.5V4.757c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0111.186 0c1.1.128 1.907 1.077 1.907 2.185zM9.75 9h.008v.008H9.75V9zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm4.125 4.5h.008v.008h-.008V13.5zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z' + }) + ] + ) +} + +const OrderIcon = { + render: () => + h( + 'svg', + { fill: 'none', viewBox: '0 0 24 24', stroke: 'currentColor', 'stroke-width': '1.5' }, + [ + h('path', { + 'stroke-linecap': 'round', + 'stroke-linejoin': 'round', + d: 'M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.25 2.25 0 002.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 00-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75 2.25 2.25 0 00-.1-.664m-5.8 0A2.251 2.251 0 0113.5 2.25H15a2.25 2.25 0 012.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25zM6.75 12h.008v.008H6.75V12zm0 3h.008v.008H6.75V15zm0 3h.008v.008H6.75V18z' + }) + ] + ) +} + +const OrderListIcon = { + render: () => + h( + 'svg', + { fill: 'none', viewBox: '0 0 24 24', stroke: 'currentColor', 'stroke-width': '1.5' }, + [ + h('path', { + 'stroke-linecap': 'round', + 'stroke-linejoin': 'round', + d: 'M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z' + }) + ] + ) +} + const ChevronDoubleRightIcon = { render: () => h( @@ -489,13 +549,22 @@ const userNavItems = computed((): NavItem[] => { { path: '/keys', label: t('nav.apiKeys'), icon: KeyIcon }, { path: '/usage', label: t('nav.usage'), icon: ChartIcon, hideInSimpleMode: true }, { path: '/subscriptions', label: t('nav.mySubscriptions'), icon: CreditCardIcon, hideInSimpleMode: true }, - ...(appStore.cachedPublicSettings?.purchase_subscription_enabled + ...(appStore.cachedPublicSettings?.sora_client_enabled + ? [{ path: '/sora', label: t('nav.sora'), icon: SoraIcon }] + : []), + ...(appStore.cachedPublicSettings?.payment_enabled || appStore.cachedPublicSettings?.purchase_subscription_enabled ? [ { path: '/purchase', label: t('nav.buySubscription'), icon: RechargeSubscriptionIcon, hideInSimpleMode: true + }, + { + path: '/orders', + label: t('nav.myOrders'), + icon: OrderListIcon, + hideInSimpleMode: true } ] : []), @@ -517,13 +586,22 @@ const personalNavItems = computed((): NavItem[] => { { path: '/keys', label: t('nav.apiKeys'), icon: KeyIcon }, { path: '/usage', label: t('nav.usage'), icon: ChartIcon, hideInSimpleMode: true }, { path: '/subscriptions', label: t('nav.mySubscriptions'), icon: CreditCardIcon, hideInSimpleMode: true }, - ...(appStore.cachedPublicSettings?.purchase_subscription_enabled + ...(appStore.cachedPublicSettings?.sora_client_enabled + ? [{ path: '/sora', label: t('nav.sora'), icon: SoraIcon }] + : []), + ...(appStore.cachedPublicSettings?.payment_enabled || appStore.cachedPublicSettings?.purchase_subscription_enabled ? [ { path: '/purchase', label: t('nav.buySubscription'), icon: RechargeSubscriptionIcon, hideInSimpleMode: true + }, + { + path: '/orders', + label: t('nav.myOrders'), + icon: OrderListIcon, + hideInSimpleMode: true } ] : []), @@ -569,6 +647,9 @@ const adminNavItems = computed((): NavItem[] => { { path: '/admin/proxies', label: t('nav.proxies'), icon: ServerIcon }, { path: '/admin/redeem', label: t('nav.redeemCodes'), icon: TicketIcon, hideInSimpleMode: true }, { path: '/admin/promo-codes', label: t('nav.promoCodes'), icon: GiftIcon, hideInSimpleMode: true }, + ...(adminSettingsStore.paymentEnabled + ? [{ path: '/admin/orders', label: t('nav.orderManagement'), icon: OrderIcon, hideInSimpleMode: true }] + : []), { path: '/admin/usage', label: t('nav.usage'), icon: ChartIcon } ] diff --git a/frontend/src/components/payment/AmountInput.vue b/frontend/src/components/payment/AmountInput.vue new file mode 100644 index 0000000000..0b0f0e8886 --- /dev/null +++ b/frontend/src/components/payment/AmountInput.vue @@ -0,0 +1,103 @@ + + + diff --git a/frontend/src/components/payment/OrderStatusBadge.vue b/frontend/src/components/payment/OrderStatusBadge.vue new file mode 100644 index 0000000000..a0425492a2 --- /dev/null +++ b/frontend/src/components/payment/OrderStatusBadge.vue @@ -0,0 +1,45 @@ + + + diff --git a/frontend/src/components/payment/PaymentMethodSelector.vue b/frontend/src/components/payment/PaymentMethodSelector.vue new file mode 100644 index 0000000000..e232256d46 --- /dev/null +++ b/frontend/src/components/payment/PaymentMethodSelector.vue @@ -0,0 +1,88 @@ + + + diff --git a/frontend/src/components/payment/SubscriptionPlanCard.vue b/frontend/src/components/payment/SubscriptionPlanCard.vue new file mode 100644 index 0000000000..55b51a59d7 --- /dev/null +++ b/frontend/src/components/payment/SubscriptionPlanCard.vue @@ -0,0 +1,105 @@ + + + diff --git a/frontend/src/i18n/locales/en.ts b/frontend/src/i18n/locales/en.ts index fca0b20a60..86e2def63d 100644 --- a/frontend/src/i18n/locales/en.ts +++ b/frontend/src/i18n/locales/en.ts @@ -352,7 +352,10 @@ export default { github: 'GitHub', mySubscriptions: 'My Subscriptions', buySubscription: 'Recharge / Subscription', - docs: 'Docs' + docs: 'Docs', + sora: 'Sora Studio', + myOrders: 'My Orders', + orderManagement: 'Order Management', }, // Auth @@ -4137,6 +4140,8 @@ export default { gateway: 'Gateway', email: 'Email', backup: 'Backup', + data: 'Sora Storage', + payment: 'Payment', }, emailTabDisabledTitle: 'Email Verification Not Enabled', emailTabDisabledHint: 'Enable email verification in the Security tab to configure SMTP settings.', @@ -4321,6 +4326,23 @@ export default { moveUp: 'Move Up', moveDown: 'Move Down', }, + payment: { + title: 'Payment Settings', + description: 'Configure payment system options', + enabled: 'Enable Payment', + enabledHint: 'Enable or disable the payment system', + enabledPaymentTypes: 'Enabled Payment Types', + enabledPaymentTypesHint: 'Select which payment methods to display', + minAmount: 'Minimum Amount', + maxAmount: 'Maximum Amount', + dailyLimit: 'Daily Limit', + orderTimeout: 'Order Timeout', + maxPendingOrders: 'Max Pending Orders', + helpText: 'Help Text', + helpImageUrl: 'Help Image URL', + manageProviders: 'Manage Providers', + balancePaymentDisabled: 'Balance payment is disabled', + }, smtp: { title: 'SMTP Settings', description: 'Configure email sending for verification codes', @@ -4866,4 +4888,268 @@ export default { } }, + // Sora Studio + sora: { + title: 'Sora Studio', + description: 'Generate videos and images with Sora AI', + notEnabled: 'Feature Not Available', + notEnabledDesc: 'The Sora Studio feature has not been enabled by the administrator. Please contact your admin.', + tabGenerate: 'Generate', + tabLibrary: 'Library', + noActiveGenerations: 'No active generations', + startGenerating: 'Enter a prompt below to start creating', + storage: 'Storage', + promptPlaceholder: 'Describe what you want to create...', + generate: 'Generate', + generating: 'Generating...', + selectModel: 'Select Model', + statusPending: 'Pending', + statusGenerating: 'Generating', + statusCompleted: 'Completed', + statusFailed: 'Failed', + statusCancelled: 'Cancelled', + cancel: 'Cancel', + delete: 'Delete', + save: 'Save to Cloud', + saved: 'Saved', + retry: 'Retry', + download: 'Download', + justNow: 'Just now', + minutesAgo: '{n} min ago', + hoursAgo: '{n} hr ago', + noSavedWorks: 'No saved works', + saveWorksHint: 'Save your completed generations to the library', + filterAll: 'All', + filterVideo: 'Video', + filterImage: 'Image', + confirmDelete: 'Are you sure you want to delete this work?', + loading: 'Loading...', + loadMore: 'Load More', + noStorageWarningTitle: 'No Storage Configured', + noStorageWarningDesc: 'Generated content is only available via temporary upstream links that expire in ~15 minutes. Consider configuring S3 storage.', + mediaTypeVideo: 'Video', + mediaTypeImage: 'Image', + notificationCompleted: 'Generation Complete', + notificationFailed: 'Generation Failed', + notificationCompletedBody: 'Your {model} task has completed', + notificationFailedBody: 'Your {model} task has failed', + upstreamExpiresSoon: 'Expiring soon', + upstreamExpired: 'Link expired', + upstreamCountdown: '{time} remaining', + previewTitle: 'Preview', + closePreview: 'Close', + beforeUnloadWarning: 'You have unsaved generated content. Are you sure you want to leave?', + downloadTitle: 'Download Generated Content', + downloadExpirationWarning: 'This link expires in approximately 15 minutes. Please download and save promptly.', + downloadNow: 'Download Now', + referenceImage: 'Reference Image', + removeImage: 'Remove', + imageTooLarge: 'Image size cannot exceed 20MB', + // Sora dark theme additions + welcomeTitle: 'Turn your imagination into video', + welcomeSubtitle: 'Enter a description and Sora will create realistic videos or images for you. Try the examples below to get started.', + queueTasks: 'tasks', + queueWaiting: 'Queued', + waiting: 'Waiting', + waited: 'Waited', + errorCategory: 'Content Policy Violation', + savedToCloud: 'Saved to Cloud', + downloadLocal: 'Download', + canDownload: 'to download', + regenrate: 'Regenerate', + regenerate: 'Regenerate', + creatorPlaceholder: 'Describe the video or image you want to create...', + videoModels: 'Video Models', + imageModels: 'Image Models', + noStorageConfigured: 'No Storage', + selectCredential: 'Select Credential', + apiKeys: 'API Keys', + subscriptions: 'Subscriptions', + subscription: 'Subscription', + noCredentialHint: 'Please create an API Key or contact admin for subscription', + uploadReference: 'Upload reference image', + generatingCount: 'Generating {current}/{max}', + noStorageToastMessage: 'Cloud storage is not configured. Please use "Download" to save files after generation, otherwise they will be lost.', + galleryCount: '{count} works', + galleryEmptyTitle: 'No works yet', + galleryEmptyDesc: 'Your creations will be displayed here. Go to the generate page to start your first creation.', + startCreating: 'Start Creating', + yesterday: 'Yesterday', + landscape: 'Landscape', + portrait: 'Portrait', + square: 'Square', + examplePrompt1: 'A golden Shiba Inu walking through the streets of Shibuya, Tokyo, camera following, cinematic shot, 4K', + examplePrompt2: 'Drone aerial view, green aurora reflecting on a glacial lake in Iceland, slow push-in', + examplePrompt3: 'Cyberpunk futuristic city, neon lights reflected in rain puddles, nightscape, cinematic colors', + examplePrompt4: 'Chinese ink painting style, a small boat drifting among misty mountains and rivers, classical atmosphere' + }, + + // Payment System + payment: { + title: 'Recharge / Subscription', + amountLabel: 'Amount', + quickAmounts: 'Quick Amounts', + customAmount: 'Custom Amount', + paymentMethod: 'Payment Method', + fee: 'Fee', + actualPay: 'Actual Payment', + createOrder: 'Confirm Payment', + methods: { + alipay: 'Alipay', + wxpay: 'WeChat Pay', + stripe: 'Stripe', + alipay_direct: 'Alipay (Direct)', + wxpay_direct: 'WeChat Pay (Direct)', + }, + status: { + pending: 'Pending', + paid: 'Paid', + recharging: 'Recharging', + completed: 'Completed', + expired: 'Expired', + cancelled: 'Cancelled', + failed: 'Failed', + refund_requested: 'Refund Requested', + refunding: 'Refunding', + refunded: 'Refunded', + partially_refunded: 'Partially Refunded', + refund_failed: 'Refund Failed', + }, + qr: { + scanToPay: 'Scan to Pay', + expiresIn: 'Expires in', + expired: 'Order Expired', + waitingPayment: 'Waiting for payment...', + }, + orders: { + title: 'My Orders', + empty: 'No orders yet', + orderId: 'Order ID', + amount: 'Amount', + payAmount: 'Paid', + status: 'Status', + paymentMethod: 'Payment Method', + createdAt: 'Created', + cancel: 'Cancel Order', + userId: 'User ID', + requestRefund: 'Request Refund', + }, + result: { + success: 'Payment Successful', + failed: 'Payment Failed', + backToRecharge: 'Back to Recharge', + viewOrders: 'View Orders', + }, + currentBalance: 'Current Balance', + tabTopUp: 'Top Up', + tabSubscribe: 'Subscribe', + noPlans: 'No subscription plans available', + confirmSubscription: 'Confirm Subscription', + confirmCancel: 'Are you sure you want to cancel this order?', + amountTooLow: 'Minimum amount is {min}', + amountTooHigh: 'Maximum amount is {max}', + refundReason: 'Refund Reason', + refundReasonPlaceholder: 'Please describe your refund reason', + stripeLoadFailed: 'Failed to load payment component. Please refresh and try again.', + stripePay: 'Pay Now', + stripeSuccessProcessing: 'Payment successful, processing your order...', + subscribeNow: 'Subscribe Now', + planFeatures: 'Features', + days: 'days', + months: 'months', + years: 'years', + oneMonth: '1 Month', + oneYear: '1 Year', + perMonth: 'month', + perYear: 'year', + admin: { + tabs: { + overview: 'Overview', + orders: 'Orders', + channels: 'Channels', + plans: 'Plans', + }, + todayRevenue: 'Today Revenue', + totalRevenue: 'Total Revenue', + todayOrders: 'Today Orders', + orderCount: 'Order Count', + avgAmount: 'Average Amount', + revenue: 'Revenue', + dailyRevenue: 'Daily Revenue', + paymentDistribution: 'Payment Distribution', + topUsers: 'Top Users', + noData: 'No data', + days: 'days', + weeks: 'weeks', + months: 'months', + searchOrders: 'Search orders...', + allStatuses: 'All Statuses', + allPaymentTypes: 'All Payment Types', + allOrderTypes: 'All Order Types', + orderDetail: 'Order Detail', + orderType: 'Order Type', + orders: 'Orders', + balanceOrder: 'Balance Top-Up', + subscriptionOrder: 'Subscription', + paidAt: 'Paid At', + completedAt: 'Completed At', + expiresAt: 'Expires At', + feeRate: 'Fee Rate', + refund: 'Refund', + refundOrder: 'Refund Order', + refundAmount: 'Refund Amount', + maxRefundable: 'Max Refundable', + refundReason: 'Refund Reason', + refundReasonPlaceholder: 'Please enter refund reason', + confirmRefund: 'Confirm Refund', + refundSuccess: 'Refund successful', + refundInfo: 'Refund Info', + refundEnabled: 'Refund Enabled', + alreadyRefunded: 'Already Refunded', + deductBalance: 'Deduct Balance', + orderCancelled: 'Order Cancelled', + retry: 'Retry', + retrySuccess: 'Retry successful', + channelName: 'Channel Name', + channelDescription: 'Channel Description', + createChannel: 'Create Channel', + editChannel: 'Edit Channel', + deleteChannel: 'Delete Channel', + deleteChannelConfirm: 'Are you sure you want to delete this channel?', + planName: 'Plan Name', + planDescription: 'Plan Description', + createPlan: 'Create Plan', + editPlan: 'Edit Plan', + deletePlan: 'Delete Plan', + deletePlanConfirm: 'Are you sure you want to delete this plan?', + originalPrice: 'Original Price', + price: 'Price', + validityDays: 'Validity (days)', + validityUnit: 'Validity Unit', + sortOrder: 'Sort Order', + forSale: 'For Sale', + onSale: 'On Sale', + offSale: 'Off Sale', + groupId: 'Group ID', + features: 'Features', + featuresHint: 'One feature per line', + featuresPlaceholder: 'Enter plan features...', + providerManagement: 'Provider Management', + providerManagementDesc: 'Manage payment provider instances', + createProvider: 'Create Provider', + editProvider: 'Edit Provider', + deleteProvider: 'Delete Provider', + deleteProviderConfirm: 'Are you sure you want to delete this provider?', + providerName: 'Provider Name', + providerKey: 'Provider Key', + selectProviderKey: 'Select Provider Key', + providerConfig: 'Provider Config', + noProviders: 'No providers configured', + noProvidersHint: 'Create a provider instance to start accepting payments', + supportedTypes: 'Supported Payment Types', + supportedTypesHint: 'Select the payment types this provider supports', + rateMultiplier: 'Rate Multiplier', + }, + }, + } diff --git a/frontend/src/i18n/locales/zh.ts b/frontend/src/i18n/locales/zh.ts index c2d7546ac6..9901c8d705 100644 --- a/frontend/src/i18n/locales/zh.ts +++ b/frontend/src/i18n/locales/zh.ts @@ -352,7 +352,10 @@ export default { github: 'GitHub', mySubscriptions: '我的订阅', buySubscription: '充值/订阅', - docs: '文档' + docs: '文档', + sora: 'Sora 创作', + myOrders: '我的订单', + orderManagement: '订单管理', }, // Auth @@ -4311,6 +4314,8 @@ export default { gateway: '网关服务', email: '邮件设置', backup: '数据备份', + data: 'Sora 存储', + payment: '支付设置', }, emailTabDisabledTitle: '邮箱验证未启用', emailTabDisabledHint: '请在「安全与认证」选项卡中启用邮箱验证后,再配置 SMTP 设置。', @@ -4494,6 +4499,23 @@ export default { moveUp: '上移', moveDown: '下移', }, + payment: { + title: '支付设置', + description: '配置支付系统选项', + enabled: '启用支付', + enabledHint: '启用或禁用支付系统', + enabledPaymentTypes: '启用的支付方式', + enabledPaymentTypesHint: '选择要显示的支付方式', + minAmount: '最低金额', + maxAmount: '最高金额', + dailyLimit: '每日限额', + orderTimeout: '订单超时时间', + maxPendingOrders: '最大待支付订单数', + helpText: '帮助文本', + helpImageUrl: '帮助图片链接', + manageProviders: '管理服务商', + balancePaymentDisabled: '余额支付已禁用', + }, smtp: { title: 'SMTP 设置', description: '配置用于发送验证码的邮件服务', @@ -5063,4 +5085,268 @@ export default { } }, + // Sora 创作 + sora: { + title: 'Sora 创作', + description: '使用 Sora AI 生成视频与图片', + notEnabled: '功能未开放', + notEnabledDesc: '管理员尚未启用 Sora 创作功能,请联系管理员开通。', + tabGenerate: '生成', + tabLibrary: '作品库', + noActiveGenerations: '暂无生成任务', + startGenerating: '在下方输入提示词,开始创作', + storage: '存储', + promptPlaceholder: '描述你想创作的内容...', + generate: '生成', + generating: '生成中...', + selectModel: '选择模型', + statusPending: '等待中', + statusGenerating: '生成中', + statusCompleted: '已完成', + statusFailed: '失败', + statusCancelled: '已取消', + cancel: '取消', + delete: '删除', + save: '保存到云端', + saved: '已保存', + retry: '重试', + download: '下载', + justNow: '刚刚', + minutesAgo: '{n} 分钟前', + hoursAgo: '{n} 小时前', + noSavedWorks: '暂无保存的作品', + saveWorksHint: '生成完成后,将作品保存到作品库', + filterAll: '全部', + filterVideo: '视频', + filterImage: '图片', + confirmDelete: '确定删除此作品?', + loading: '加载中...', + loadMore: '加载更多', + noStorageWarningTitle: '未配置存储', + noStorageWarningDesc: '生成的内容仅通过上游临时链接提供,约 15 分钟后过期。建议管理员配置 S3 存储。', + mediaTypeVideo: '视频', + mediaTypeImage: '图片', + notificationCompleted: '生成完成', + notificationFailed: '生成失败', + notificationCompletedBody: '您的 {model} 任务已完成', + notificationFailedBody: '您的 {model} 任务失败了', + upstreamExpiresSoon: '即将过期', + upstreamExpired: '链接已过期', + upstreamCountdown: '剩余 {time}', + previewTitle: '作品预览', + closePreview: '关闭', + beforeUnloadWarning: '您有未保存的生成内容,确定要离开吗?', + downloadTitle: '下载生成内容', + downloadExpirationWarning: '此链接约 15 分钟后过期,请尽快下载保存。', + downloadNow: '立即下载', + referenceImage: '参考图', + removeImage: '移除', + imageTooLarge: '图片大小不能超过 20MB', + // Sora 暗色主题新增 + welcomeTitle: '将你的想象力变成视频', + welcomeSubtitle: '输入一段描述,Sora 将为你创作逼真的视频或图片。尝试以下示例开始创作。', + queueTasks: '个任务', + queueWaiting: '队列中等待', + waiting: '等待中', + waited: '已等待', + errorCategory: '内容策略限制', + savedToCloud: '已保存到云端', + downloadLocal: '本地下载', + canDownload: '可下载', + regenrate: '重新生成', + regenerate: '重新生成', + creatorPlaceholder: '描述你想要生成的视频或图片...', + videoModels: '视频模型', + imageModels: '图片模型', + noStorageConfigured: '存储未配置', + selectCredential: '选择凭证', + apiKeys: 'API 密钥', + subscriptions: '订阅', + subscription: '订阅', + noCredentialHint: '请先创建 API Key 或联系管理员分配订阅', + uploadReference: '上传参考图片', + generatingCount: '正在生成 {current}/{max}', + noStorageToastMessage: '管理员未开通云存储,生成完成后请使用"本地下载"保存文件,否则将会丢失。', + galleryCount: '共 {count} 个作品', + galleryEmptyTitle: '还没有任何作品', + galleryEmptyDesc: '你的创作成果将会展示在这里。前往生成页,开始你的第一次创作吧。', + startCreating: '开始创作', + yesterday: '昨天', + landscape: '横屏', + portrait: '竖屏', + square: '方形', + examplePrompt1: '一只金色的柴犬在东京涩谷街头散步,镜头跟随,电影感画面,4K 高清', + examplePrompt2: '无人机航拍视角,冰岛极光下的冰川湖面反射绿色光芒,慢速推进', + examplePrompt3: '赛博朋克风格的未来城市,霓虹灯倒映在雨后积水中,夜景,电影级色彩', + examplePrompt4: '水墨画风格,一叶扁舟在山水间漂泊,薄雾缭绕,中国古典意境' + }, + + // Payment System + payment: { + title: '充值/订阅', + amountLabel: '充值金额', + quickAmounts: '快捷金额', + customAmount: '自定义金额', + paymentMethod: '支付方式', + fee: '手续费', + actualPay: '实付金额', + createOrder: '确认支付', + methods: { + alipay: '支付宝', + wxpay: '微信支付', + stripe: 'Stripe', + alipay_direct: '支付宝(直连)', + wxpay_direct: '微信支付(直连)', + }, + status: { + pending: '待支付', + paid: '已支付', + recharging: '充值中', + completed: '已完成', + expired: '已过期', + cancelled: '已取消', + failed: '失败', + refund_requested: '退款申请中', + refunding: '退款中', + refunded: '已退款', + partially_refunded: '部分退款', + refund_failed: '退款失败', + }, + qr: { + scanToPay: '请扫码支付', + expiresIn: '剩余支付时间', + expired: '订单已过期', + waitingPayment: '等待支付...', + }, + orders: { + title: '我的订单', + empty: '暂无订单', + orderId: '订单号', + amount: '金额', + payAmount: '实付', + status: '状态', + paymentMethod: '支付方式', + createdAt: '创建时间', + cancel: '取消订单', + userId: '用户 ID', + requestRefund: '申请退款', + }, + result: { + success: '支付成功', + failed: '支付失败', + backToRecharge: '返回充值', + viewOrders: '查看订单', + }, + currentBalance: '当前余额', + tabTopUp: '充值', + tabSubscribe: '订阅', + noPlans: '暂无可用订阅套餐', + confirmSubscription: '确认订阅', + confirmCancel: '确定要取消此订单吗?', + amountTooLow: '最低金额为 {min}', + amountTooHigh: '最高金额为 {max}', + refundReason: '退款原因', + refundReasonPlaceholder: '请描述您的退款原因', + stripeLoadFailed: '支付组件加载失败,请刷新页面重试', + stripePay: '立即支付', + stripeSuccessProcessing: '支付成功,正在处理订单...', + subscribeNow: '立即开通', + planFeatures: '功能特性', + days: '天', + months: '个月', + years: '年', + oneMonth: '1 个月', + oneYear: '1 年', + perMonth: '月', + perYear: '年', + admin: { + tabs: { + overview: '概览', + orders: '订单管理', + channels: '支付渠道', + plans: '订阅套餐', + }, + todayRevenue: '今日收入', + totalRevenue: '总收入', + todayOrders: '今日订单', + orderCount: '订单数', + avgAmount: '平均金额', + revenue: '收入', + dailyRevenue: '每日收入', + paymentDistribution: '支付方式分布', + topUsers: '消费排行', + noData: '暂无数据', + days: '天', + weeks: '周', + months: '月', + searchOrders: '搜索订单...', + allStatuses: '全部状态', + allPaymentTypes: '全部支付方式', + allOrderTypes: '全部订单类型', + orderDetail: '订单详情', + orderType: '订单类型', + orders: '订单', + balanceOrder: '余额充值', + subscriptionOrder: '订阅', + paidAt: '支付时间', + completedAt: '完成时间', + expiresAt: '过期时间', + feeRate: '手续费率', + refund: '退款', + refundOrder: '退款订单', + refundAmount: '退款金额', + maxRefundable: '最大可退金额', + refundReason: '退款原因', + refundReasonPlaceholder: '请输入退款原因', + confirmRefund: '确认退款', + refundSuccess: '退款成功', + refundInfo: '退款信息', + refundEnabled: '允许退款', + alreadyRefunded: '已退款', + deductBalance: '扣除余额', + orderCancelled: '订单已取消', + retry: '重试', + retrySuccess: '重试成功', + channelName: '渠道名称', + channelDescription: '渠道描述', + createChannel: '创建渠道', + editChannel: '编辑渠道', + deleteChannel: '删除渠道', + deleteChannelConfirm: '确定要删除此渠道吗?', + planName: '套餐名称', + planDescription: '套餐描述', + createPlan: '创建套餐', + editPlan: '编辑套餐', + deletePlan: '删除套餐', + deletePlanConfirm: '确定要删除此套餐吗?', + originalPrice: '原价', + price: '价格', + validityDays: '有效期(天)', + validityUnit: '有效期单位', + sortOrder: '排序', + forSale: '上架状态', + onSale: '上架', + offSale: '下架', + groupId: '分组 ID', + features: '功能特性', + featuresHint: '每行一个特性', + featuresPlaceholder: '输入套餐特性...', + providerManagement: '服务商管理', + providerManagementDesc: '管理支付服务商实例', + createProvider: '创建服务商', + editProvider: '编辑服务商', + deleteProvider: '删除服务商', + deleteProviderConfirm: '确定要删除此服务商吗?', + providerName: '服务商名称', + providerKey: '服务商标识', + selectProviderKey: '选择服务商标识', + providerConfig: '服务商配置', + noProviders: '暂无服务商', + noProvidersHint: '创建一个服务商实例以开始接受支付', + supportedTypes: '支持的支付方式', + supportedTypesHint: '选择此服务商支持的支付方式', + rateMultiplier: '费率倍数', + }, + }, + } diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index 6faf6f598f..62221739e6 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -192,13 +192,62 @@ const routes: RouteRecordRaw[] = [ { path: '/purchase', name: 'PurchaseSubscription', - component: () => import('@/views/user/PurchaseSubscriptionView.vue'), + component: () => import('@/views/user/PaymentView.vue'), meta: { requiresAuth: true, requiresAdmin: false, title: 'Purchase Subscription', titleKey: 'purchase.title', - descriptionKey: 'purchase.description' + descriptionKey: 'purchase.description', + requiresPayment: true + } + }, + { + path: '/orders', + name: 'OrderList', + component: () => import('@/views/user/UserOrdersView.vue'), + meta: { + requiresAuth: true, + requiresAdmin: false, + title: 'My Orders', + titleKey: 'nav.myOrders', + requiresPayment: true + } + }, + { + path: '/payment/qrcode', + name: 'PaymentQRCode', + component: () => import('@/views/user/PaymentQRCodeView.vue'), + meta: { + requiresAuth: true, + requiresAdmin: false, + title: 'Payment', + titleKey: 'payment.qr.scanToPay', + requiresPayment: true + } + }, + { + path: '/payment/result', + name: 'PaymentResult', + component: () => import('@/views/user/PaymentResultView.vue'), + meta: { + requiresAuth: true, + requiresAdmin: false, + title: 'Payment Result', + titleKey: 'payment.result.success', + requiresPayment: true + } + }, + { + path: '/payment/stripe', + name: 'StripePayment', + component: () => import('@/views/user/StripePaymentView.vue'), + meta: { + requiresAuth: true, + requiresAdmin: false, + title: 'Stripe Payment', + titleKey: 'payment.stripePay', + requiresPayment: true } }, { @@ -375,6 +424,32 @@ const routes: RouteRecordRaw[] = [ } }, + + // ==================== Payment Admin Routes ==================== + { + path: '/admin/orders', + name: 'AdminOrders', + component: () => import('@/views/admin/orders/AdminOrdersView.vue'), + meta: { + requiresAuth: true, + requiresAdmin: true, + title: 'Order Management', + titleKey: 'nav.orderManagement', + requiresPayment: true + } + }, + { + path: '/admin/orders/providers', + name: 'AdminProviders', + component: () => import('@/views/admin/orders/AdminProvidersView.vue'), + meta: { + requiresAuth: true, + requiresAdmin: true, + title: 'Provider Management', + requiresPayment: true + } + }, + // ==================== 404 Not Found ==================== { path: '/:pathMatch(.*)*', @@ -491,6 +566,16 @@ router.beforeEach((to, _from, next) => { return } + + // Check payment requirement + if (to.meta.requiresPayment) { + const paymentEnabled = appStore.cachedPublicSettings?.payment_enabled + if (!paymentEnabled) { + next(authStore.isAdmin ? '/admin/dashboard' : '/dashboard') + return + } + } + // 简易模式下限制访问某些页面 if (authStore.isSimpleMode) { const restrictedPaths = [ diff --git a/frontend/src/stores/adminSettings.ts b/frontend/src/stores/adminSettings.ts index 76010c5ef9..7717dda73d 100644 --- a/frontend/src/stores/adminSettings.ts +++ b/frontend/src/stores/adminSettings.ts @@ -48,6 +48,7 @@ export const useAdminSettingsStore = defineStore('adminSettings', () => { const opsMonitoringEnabled = ref(readCachedBool('ops_monitoring_enabled_cached', true)) const opsRealtimeMonitoringEnabled = ref(readCachedBool('ops_realtime_monitoring_enabled_cached', true)) const opsQueryModeDefault = ref(readCachedString('ops_query_mode_default_cached', 'auto')) + const paymentEnabled = ref(readCachedBool('payment_enabled_cached', false)) const customMenuItems = ref([]) async function fetch(force = false): Promise { @@ -68,6 +69,9 @@ export const useAdminSettingsStore = defineStore('adminSettings', () => { customMenuItems.value = Array.isArray(settings.custom_menu_items) ? settings.custom_menu_items : [] + paymentEnabled.value = settings.payment_enabled ?? false + writeCachedBool('payment_enabled_cached', paymentEnabled.value) + loaded.value = true } catch (err) { // Keep cached/default value: do not "flip" the UI based on a transient fetch failure. @@ -90,6 +94,12 @@ export const useAdminSettingsStore = defineStore('adminSettings', () => { loaded.value = true } + function setPaymentEnabledLocal(value: boolean) { + paymentEnabled.value = value + writeCachedBool('payment_enabled_cached', value) + loaded.value = true + } + function setOpsQueryModeDefaultLocal(value: string) { opsQueryModeDefault.value = value || 'auto' writeCachedString('ops_query_mode_default_cached', opsQueryModeDefault.value) @@ -126,10 +136,12 @@ export const useAdminSettingsStore = defineStore('adminSettings', () => { opsMonitoringEnabled, opsRealtimeMonitoringEnabled, opsQueryModeDefault, + paymentEnabled, customMenuItems, fetch, setOpsMonitoringEnabledLocal, setOpsRealtimeMonitoringEnabledLocal, + setPaymentEnabledLocal, setOpsQueryModeDefaultLocal } }) diff --git a/frontend/src/stores/app.ts b/frontend/src/stores/app.ts index 24057136b3..d4fe7b9860 100644 --- a/frontend/src/stores/app.ts +++ b/frontend/src/stores/app.ts @@ -328,6 +328,7 @@ export const useAppStore = defineStore('app', () => { home_content: '', hide_ccs_import_button: false, purchase_subscription_enabled: false, + payment_enabled: false, purchase_subscription_url: '', custom_menu_items: [], custom_endpoints: [], diff --git a/frontend/src/stores/index.ts b/frontend/src/stores/index.ts index 5f51807c5e..1ed5e71f78 100644 --- a/frontend/src/stores/index.ts +++ b/frontend/src/stores/index.ts @@ -9,6 +9,7 @@ export { useAdminSettingsStore } from './adminSettings' export { useSubscriptionStore } from './subscriptions' export { useOnboardingStore } from './onboarding' export { useAnnouncementStore } from './announcements' +export { usePaymentStore } from './payment' // Re-export types for convenience export type { User, LoginRequest, RegisterRequest, AuthResponse } from '@/types' diff --git a/frontend/src/stores/payment.ts b/frontend/src/stores/payment.ts new file mode 100644 index 0000000000..a446d3fc67 --- /dev/null +++ b/frontend/src/stores/payment.ts @@ -0,0 +1,100 @@ +/** + * Payment Store + * Manages payment configuration, current order state, and subscription plans + */ + +import { defineStore } from 'pinia' +import { ref } from 'vue' +import { paymentAPI } from '@/api/payment' +import type { PaymentConfig, PaymentOrder, SubscriptionPlan } from '@/types/payment' + +export const usePaymentStore = defineStore('payment', () => { + // ==================== State ==================== + + /** Payment configuration from backend */ + const config = ref(null) + /** Currently active order (for payment flow) */ + const currentOrder = ref(null) + /** Available subscription plans */ + const plans = ref([]) + + const configLoading = ref(false) + const configLoaded = ref(false) + + // ==================== Actions ==================== + + /** Fetch payment configuration */ + async function fetchConfig(force = false): Promise { + if (configLoaded.value && !force) return config.value + if (configLoading.value) return config.value + + configLoading.value = true + try { + const response = await paymentAPI.getConfig() + config.value = response.data + configLoaded.value = true + return config.value + } catch (error) { + console.error('[payment] Failed to fetch config:', error) + return null + } finally { + configLoading.value = false + } + } + + /** Fetch available subscription plans */ + async function fetchPlans(): Promise { + try { + const response = await paymentAPI.getPlans() + plans.value = response.data + return plans.value + } catch (error) { + console.error('[payment] Failed to fetch plans:', error) + return [] + } + } + + /** Create a new order and set it as current */ + async function createOrder(params: { + amount: number + payment_type: string + order_type: string + plan_id?: number + }) { + const response = await paymentAPI.createOrder(params) + return response.data + } + + /** Poll order status by ID */ + async function pollOrderStatus(orderId: number): Promise { + try { + const response = await paymentAPI.getOrder(orderId) + const order = response.data + if (currentOrder.value?.id === orderId) { + currentOrder.value = order + } + return order + } catch (error) { + console.error('[payment] Failed to poll order status:', error) + return null + } + } + + /** Clear current order state */ + function clearCurrentOrder() { + currentOrder.value = null + } + + return { + config, + currentOrder, + plans, + configLoading, + configLoaded, + fetchConfig, + fetchPlans, + createOrder, + pollOrderStatus, + clearCurrentOrder + } +}) diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index d7150f2a87..1fc9316d60 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -105,6 +105,7 @@ export interface PublicSettings { home_content: string hide_ccs_import_button: boolean purchase_subscription_enabled: boolean + payment_enabled: boolean purchase_subscription_url: string custom_menu_items: CustomMenuItem[] custom_endpoints: CustomEndpoint[] diff --git a/frontend/src/types/payment.ts b/frontend/src/types/payment.ts new file mode 100644 index 0000000000..9d24ac2307 --- /dev/null +++ b/frontend/src/types/payment.ts @@ -0,0 +1,138 @@ +/** + * Payment System Type Definitions + */ + +// ==================== Enums / Union Types ==================== + +export type OrderStatus = + | 'PENDING' + | 'PAID' + | 'RECHARGING' + | 'COMPLETED' + | 'EXPIRED' + | 'CANCELLED' + | 'FAILED' + | 'REFUND_REQUESTED' + | 'REFUNDING' + | 'PARTIALLY_REFUNDED' + | 'REFUNDED' + | 'REFUND_FAILED' + +export type PaymentType = 'alipay' | 'wxpay' | 'alipay_direct' | 'wxpay_direct' | 'stripe' + +export type OrderType = 'balance' | 'subscription' + +// ==================== Configuration ==================== + +export interface PaymentConfig { + payment_enabled: boolean + min_amount: number + max_amount: number + daily_limit: number + max_pending_orders: number + order_timeout_minutes: number + balance_disabled: boolean + enabled_payment_types: PaymentType[] + help_image_url: string + help_text: string + stripe_publishable_key: string +} + +export interface MethodLimit { + daily_limit: number + daily_used: number + daily_remaining: number + single_min: number + single_max: number + fee_rate: number + available: boolean +} + +// ==================== Orders ==================== + +export interface PaymentOrder { + id: number + user_id: number + amount: number + pay_amount: number + fee_rate: number + payment_type: string + status: OrderStatus + order_type: OrderType + created_at: string + expires_at: string + paid_at?: string + completed_at?: string + refund_amount: number + refund_reason?: string + plan_id?: number +} + +// ==================== Plans & Channels ==================== + +export interface SubscriptionPlan { + id: number + group_id: number + name: string + description: string + price: number + original_price?: number + validity_days: number + validity_unit: string + /** Stored as JSON string in backend; API layer should parse before use */ + features: string[] + for_sale: boolean + sort_order: number +} + +export interface PaymentChannel { + id: number + group_id?: number + name: string + platform: string + rate_multiplier: number + description: string + models: string[] + features: string[] + enabled: boolean +} + +// ==================== Providers ==================== + +export interface ProviderInstance { + id: number + provider_key: string + name: string + supported_types: string + enabled: boolean + refund_enabled: boolean +} + +// ==================== Request / Response ==================== + +export interface CreateOrderRequest { + amount: number + payment_type: string + order_type: string + plan_id?: number +} + +export interface CreateOrderResult { + order_id: number + pay_url?: string + qr_code?: string + client_secret?: string + pay_amount: number + expires_at: string +} + +export interface DashboardStats { + today_amount: number + total_amount: number + today_count: number + total_count: number + avg_amount: number + daily_series: { date: string; amount: number; count: number }[] + payment_methods: { type: string; amount: number; count: number }[] + top_users: { user_id: number; email: string; amount: number }[] +} diff --git a/frontend/src/views/admin/SettingsView.vue b/frontend/src/views/admin/SettingsView.vue index 1839d03cc4..e521480d81 100644 --- a/frontend/src/views/admin/SettingsView.vue +++ b/frontend/src/views/admin/SettingsView.vue @@ -1512,70 +1512,6 @@ - -
-
-

- {{ t('admin.settings.purchase.title') }} -

-

- {{ t('admin.settings.purchase.description') }} -

-
-
- -
-
- -

- {{ t('admin.settings.purchase.enabledHint') }} -

-
- -
- - -
- - -

- {{ t('admin.settings.purchase.urlHint') }} -

-

- {{ t('admin.settings.purchase.iframeWarning') }} -

-
- - -
- - - - - {{ t('admin.settings.purchase.integrationDoc') }} - - — - - {{ t('admin.settings.purchase.integrationDocHint') }} - -
-
-
@@ -1701,6 +1637,7 @@
+

{{ t('admin.settings.payment.title') }}

{{ t('admin.settings.payment.description') }}

{{ t('admin.settings.payment.enabledHint') }}

@@ -1989,13 +1926,14 @@ const { t } = useI18n() const appStore = useAppStore() const adminSettingsStore = useAdminSettingsStore() -type SettingsTab = 'general' | 'security' | 'users' | 'gateway' | 'email' | 'backup' +type SettingsTab = 'general' | 'security' | 'users' | 'gateway' | 'payment' | 'email' | 'backup' | 'data' const activeTab = ref('general') const settingsTabs = [ { key: 'general' as SettingsTab, icon: 'home' as const }, { key: 'security' as SettingsTab, icon: 'shield' as const }, { key: 'users' as SettingsTab, icon: 'user' as const }, { key: 'gateway' as SettingsTab, icon: 'server' as const }, + { key: 'payment' as SettingsTab, icon: 'creditCard' as const }, { key: 'email' as SettingsTab, icon: 'mail' as const }, { key: 'backup' as SettingsTab, icon: 'database' as const }, ] @@ -2100,6 +2038,8 @@ const form = reactive({ hide_ccs_import_button: false, purchase_subscription_enabled: false, purchase_subscription_url: '', + payment_enabled: false, payment_min_amount: 1, payment_max_amount: 10000, payment_daily_limit: 50000, payment_max_pending_orders: 3, payment_order_timeout_minutes: 30, payment_balance_disabled: false, payment_enabled_types: '', payment_help_image_url: '', payment_help_text: '', + sora_client_enabled: false, custom_menu_items: [] as Array<{id: string; label: string; icon_svg: string; url: string; visibility: 'user' | 'admin'; sort_order: number}>, custom_endpoints: [] as Array<{name: string; endpoint: string; description: string}>, frontend_url: '', @@ -2383,21 +2323,6 @@ async function saveSettings() { // Optional URL fields: auto-clear invalid values so they don't cause backend 400 errors if (!isValidHttpUrl(form.frontend_url)) form.frontend_url = '' if (!isValidHttpUrl(form.doc_url)) form.doc_url = '' - // Purchase URL: required when enabled; auto-clear when disabled to avoid backend rejection - if (form.purchase_subscription_enabled) { - if (!form.purchase_subscription_url) { - appStore.showError(t('admin.settings.purchase.url') + ': URL is required when purchase is enabled') - saving.value = false - return - } - if (!isValidHttpUrl(form.purchase_subscription_url)) { - appStore.showError(t('admin.settings.purchase.url') + ': must be an absolute http(s) URL (e.g. https://example.com)') - saving.value = false - return - } - } else if (!isValidHttpUrl(form.purchase_subscription_url)) { - form.purchase_subscription_url = '' - } const payload: UpdateSettingsRequest = { registration_enabled: form.registration_enabled, @@ -2423,6 +2348,17 @@ async function saveSettings() { hide_ccs_import_button: form.hide_ccs_import_button, purchase_subscription_enabled: form.purchase_subscription_enabled, purchase_subscription_url: form.purchase_subscription_url, + payment_enabled: form.payment_enabled, + payment_min_amount: form.payment_min_amount, + payment_max_amount: form.payment_max_amount, + payment_daily_limit: form.payment_daily_limit, + payment_max_pending_orders: form.payment_max_pending_orders, + payment_order_timeout_minutes: form.payment_order_timeout_minutes, + payment_balance_disabled: form.payment_balance_disabled, + payment_enabled_types: form.payment_enabled_types, + payment_help_image_url: form.payment_help_image_url, + payment_help_text: form.payment_help_text, + sora_client_enabled: form.sora_client_enabled, custom_menu_items: form.custom_menu_items, custom_endpoints: form.custom_endpoints, frontend_url: form.frontend_url, diff --git a/frontend/src/views/admin/orders/AdminOrdersView.vue b/frontend/src/views/admin/orders/AdminOrdersView.vue new file mode 100644 index 0000000000..7291055988 --- /dev/null +++ b/frontend/src/views/admin/orders/AdminOrdersView.vue @@ -0,0 +1,448 @@ + + + diff --git a/frontend/src/views/admin/orders/AdminProvidersView.vue b/frontend/src/views/admin/orders/AdminProvidersView.vue new file mode 100644 index 0000000000..583c8b089f --- /dev/null +++ b/frontend/src/views/admin/orders/AdminProvidersView.vue @@ -0,0 +1,287 @@ + + + diff --git a/frontend/src/views/user/PaymentQRCodeView.vue b/frontend/src/views/user/PaymentQRCodeView.vue new file mode 100644 index 0000000000..b9fa1ff212 --- /dev/null +++ b/frontend/src/views/user/PaymentQRCodeView.vue @@ -0,0 +1,96 @@ + + + diff --git a/frontend/src/views/user/PaymentResultView.vue b/frontend/src/views/user/PaymentResultView.vue new file mode 100644 index 0000000000..682f6eec11 --- /dev/null +++ b/frontend/src/views/user/PaymentResultView.vue @@ -0,0 +1,83 @@ + + + diff --git a/frontend/src/views/user/PaymentView.vue b/frontend/src/views/user/PaymentView.vue new file mode 100644 index 0000000000..190971f0e8 --- /dev/null +++ b/frontend/src/views/user/PaymentView.vue @@ -0,0 +1,265 @@ + + + + + diff --git a/frontend/src/views/user/StripePaymentView.vue b/frontend/src/views/user/StripePaymentView.vue new file mode 100644 index 0000000000..481cf547db --- /dev/null +++ b/frontend/src/views/user/StripePaymentView.vue @@ -0,0 +1,141 @@ + + + diff --git a/frontend/src/views/user/UserOrdersView.vue b/frontend/src/views/user/UserOrdersView.vue new file mode 100644 index 0000000000..c6e0db662c --- /dev/null +++ b/frontend/src/views/user/UserOrdersView.vue @@ -0,0 +1,186 @@ +