import graphene from graphene import Field, Boolean, List, String from backend.core.commands import ( CreateAccountCommand, UpdateAccountCommand, DeleteAccountCommand, MarkAccountInactiveCommand ) from backend.core.repositories import AccountRepository, CustomerRepository, RevenueRepository from backend.core.utils import parse_date from backend.graphql_api.types import AccountType from backend.graphql_api.inputs import AccountCreateInput, AccountUpdateInput class CreateAccountMutation(graphene.Mutation): """Mutation to create a new account.""" class Arguments: input = AccountCreateInput(required=True) account = Field(AccountType) success = Boolean() errors = List(String) message = String() @staticmethod def mutate(root, info, input): account_repo = AccountRepository() customer_repo = CustomerRepository() command = CreateAccountCommand( account_repo=account_repo, customer_repo=customer_repo, customer_id=input.customer_id, name=input.name, street_address=input.street_address, city=input.city, state=input.state, zip_code=input.zip_code, primary_contact_first_name=input.primary_contact_first_name, primary_contact_last_name=input.primary_contact_last_name, primary_contact_phone=input.primary_contact_phone, primary_contact_email=input.primary_contact_email, secondary_contact_first_name=input.secondary_contact_first_name, secondary_contact_last_name=input.secondary_contact_last_name, secondary_contact_phone=input.secondary_contact_phone, secondary_contact_email=input.secondary_contact_email, start_date=input.start_date, end_date=input.end_date ) result = command.execute() return { 'account': result.data, 'success': result.success, 'errors': result.errors, 'message': result.message } class UpdateAccountMutation(graphene.Mutation): """Mutation to update an existing account.""" class Arguments: input = AccountUpdateInput(required=True) account = Field(AccountType) success = Boolean() errors = List(String) message = String() @staticmethod def mutate(root, info, input): account_repo = AccountRepository() command = UpdateAccountCommand( account_repo=account_repo, account_id=input.id, name=input.name, street_address=input.street_address, city=input.city, state=input.state, zip_code=input.zip_code, primary_contact_first_name=input.primary_contact_first_name, primary_contact_last_name=input.primary_contact_last_name, primary_contact_phone=input.primary_contact_phone, primary_contact_email=input.primary_contact_email, secondary_contact_first_name=input.secondary_contact_first_name, secondary_contact_last_name=input.secondary_contact_last_name, secondary_contact_phone=input.secondary_contact_phone, secondary_contact_email=input.secondary_contact_email, start_date=input.start_date, end_date=input.end_date ) result = command.execute() return { 'account': result.data, 'success': result.success, 'errors': result.errors, 'message': result.message } class DeleteAccountMutation(graphene.Mutation): """Mutation to delete an account.""" class Arguments: id = graphene.ID(required=True) success = Boolean() errors = List(String) message = String() @staticmethod def mutate(root, info, id): account_repo = AccountRepository() command = DeleteAccountCommand(account_repo=account_repo, account_id=id) result = command.execute() return { 'account': result.data, 'success': result.success, 'errors': result.errors, 'message': result.message } class MarkAccountInactiveMutation(graphene.Mutation): """Mutation to mark an account as inactive.""" class Arguments: id = graphene.ID(required=True) end_date = graphene.String() account = Field(AccountType) success = Boolean() errors = List(String) message = String() @staticmethod def mutate(root, info, id, end_date=None): account_repo = AccountRepository() command = MarkAccountInactiveCommand( account_repo=account_repo, account_id=id, end_date=end_date ) result = command.execute() return { 'account': result.data, 'success': result.success, 'errors': result.errors, 'message': result.message } class GetAccountRevenueMutation(graphene.Mutation): """Mutation to get revenue information for an account.""" class Arguments: account_id = graphene.ID(required=True, description="ID of the account to get revenue for") start_date = graphene.String(description="Start date for revenue calculation") end_date = graphene.String(description="End date for revenue calculation") total_revenue = graphene.Float(description="Total revenue for the account") success = graphene.Boolean(description="Whether the operation was successful") errors = graphene.List(graphene.String, description="List of errors that occurred") message = graphene.String(description="Success or error message") @staticmethod def mutate(root, info, account_id, start_date=None, end_date=None): try: revenue_repo = RevenueRepository() total = revenue_repo.get_total_revenue( account_id=account_id, start_date=parse_date(start_date) if start_date else None, end_date=parse_date(end_date) if end_date else None ) return { 'total_revenue': total, 'success': True, 'errors': [], 'message': f"Successfully calculated revenue for account {account_id}" } except Exception as e: return { 'total_revenue': None, 'success': False, 'errors': [str(e)], 'message': "An error occurred while calculating account revenue" }