Skip to content
advanced Phase 92 · Enterprise Features

Company Accounts

Company accounts - company structure, roles, approvals, credit limits

45m
0 problems
Topic Progress 0%

Company Structure

Company Hierarchy

  Company (Root)
    ├── Department A
    │     ├── Team 1
    │     └── Team 2
    └── Department B
          └── Team 3

Company Service

namespace Vendor\B2B\Company\Service;

class CompanyService
{
    private CompanyRepositoryInterface $companyRepo;
    private CompanyStructureInterface $structure;

    public function createCompany(array $data): CompanyInterface
    {
        $company = $this->companyFactory->create();
        $company->setName($data['name']);
        $company->setWebsiteId($data['website_id']);
        $company->setStatus(CompanyInterface::STATUS_ACTIVE);
        $company->setCreditLimit($data['credit_limit'] ?? 0);
        $company->setRejectQuoteIf($data['reject_quote_if'] ?? false);
        $company->setRequisitionListActive($data['requisition_list_active'] ?? true);

        // Create root structure
        $rootGroup = $this->structure->createRootGroup($company->getId(), $data['name']);
        $company->setRootGroupId($rootGroup->getId());

        return $this->companyRepo->save($company);
    }

    public function addChildGroup(
        int $companyId,
        int $parentId,
        string $name
    ): CompanyGroupInterface {
        return $this->structure->addGroup($companyId, $parentId, $name);
    }
}

Company Structure Manager

namespace Vendor\B2B\Company\Structure;

class CompanyStructureManager
{
    public function getStructure(int $companyId): array
    {
        $company = $this->companyRepo->get($companyId);
        $rootGroupId = $company->getRootGroupId();

        return $this->buildTree($rootGroupId);
    }

    private function buildTree(int $groupId): array
    {
        $group = $this->groupRepo->get($groupId);
        $children = $this->groupRepo->getChildren($groupId);

        return [
            'id' => $group->getId(),
            'name' => $group->getName(),
            'children' => array_map([$this, 'buildTree'], $children),
            'users' => $this->getGroupUsers($groupId),
        ];
    }
}

Roles and Permissions

Company Roles

namespace Vendor\B2B\Company\Role;

class CompanyRoleService
{
    private RoleRepositoryInterface $roleRepo;

    public function createRole(
        int $companyId,
        array $data
    ): CompanyRoleInterface {
        $role = $this->roleFactory->create();
        $role->setCompanyId($companyId);
        $role->setName($data['name']);
        $role->setPermissions($data['permissions']);

        return $this->roleRepo->save($role);
    }

    public function getPermissions(int $roleId): array
    {
        $role = $this->roleRepo->get($roleId);
        return $role->getPermissions();
    }
}

Permission Matrix

namespace Vendor\B2B\Company\Permission;

class PermissionMatrix
{
    private array $permissions = [
        'dashboard' => ['view', 'edit'],
        'orders' => ['view', 'create', 'edit', 'delete'],
        'quotes' => ['view', 'create', 'edit', 'negotiate'],
        'requisition_lists' => ['view', 'create', 'edit', 'delete'],
        'company_profile' => ['view', 'edit'],
        'users' => ['view', 'create', 'edit', 'delete'],
    ];

    public function check(
        int $roleId,
        string $resource,
        string $action
    ): bool {
        $permissions = $this->roleService->getPermissions($roleId);

        return isset($permissions[$resource])
            && in_array($action, $permissions[$resource]);
    }
}

Approval Workflows

Approval Rule Engine

namespace Vendor\B2B\Approval\Rule;

class ApprovalRuleEngine
{
    private array $rules;

    public function evaluate(
        OrderInterface $order,
        int $customerId
    ): ApprovalResult {
        $customer = $this->customerRepo->getById($customerId);
        $companyId = $customer->getCompanyId();

        foreach ($this->rules as $rule) {
            if ($rule->matches($order, $companyId)) {
                return new ApprovalResult([
                    'requires_approval' => true,
                    'approvers' => $rule->getApprovers($companyId),
                    'rule' => $rule->getName(),
                ]);
            }
        }

        return new ApprovalResult([
            'requires_approval' => false,
        ]);
    }
}

Approval Rule Types

namespace Vendor\B2B\Approval\Rule\Type;

interface ApprovalRuleInterface
{
    public function matches(OrderInterface $order, int $companyId): bool;
    public function getApprovers(int $companyId): array;
    public function getName(): string;
}

class OrderTotalRule implements ApprovalRuleInterface
{
    private float $threshold = 1000;

    public function matches(OrderInterface $order, int $companyId): bool
    {
        return $order->getGrandTotal() > $this->threshold;
    }

    public function getApprovers(int $companyId): array
    {
        return $this->roleService->getUsersWithPermission(
            $companyId,
            'orders',
            'approve'
        );
    }
}

class CreditLimitRule implements ApprovalRuleInterface
{
    public function matches(OrderInterface $order, int $companyId): bool
    {
        $company = $this->companyRepo->get($companyId);
        $remaining = $company->getCreditAvailable();

        return $order->getGrandTotal() > $remaining;
    }
}

Credit Limits

Credit Limit Manager

namespace Vendor\B2B\Credit\Limit;

class CreditLimitManager
{
    private CompanyRepositoryInterface $companyRepo;

    public function checkCredit(
        int $companyId,
        float $orderAmount
    ): CreditCheckResult {
        $company = $this->companyRepo->get($companyId);

        $creditLimit = $company->getCreditLimit();
        $creditUsed = $company->getCreditUsed();
        $available = $creditLimit - $creditUsed;

        if ($orderAmount > $available) {
            return new CreditCheckResult([
                'approved' => false,
                'credit_limit' => $creditLimit,
                'credit_used' => $creditUsed,
                'credit_available' => $available,
                'shortfall' => $orderAmount - $available,
            ]);
        }

        return new CreditCheckResult([
            'approved' => true,
            'credit_limit' => $creditLimit,
            'credit_used' => $creditUsed,
            'credit_available' => $available,
        ]);
    }

    public function useCredit(
        int $companyId,
        float $amount,
        int $orderId
    ): void {
        $company = $this->companyRepo->get($companyId);
        $company->setCreditUsed($company->getCreditUsed() + $amount);
        $this->companyRepo->save($company);

        // Log credit usage
        $this->creditLog->log($companyId, $amount, $orderId);
    }

    public function releaseCredit(
        int $companyId,
        float $amount
    ): void {
        $company = $this->companyRepo->get($companyId);
        $company->setCreditUsed(max(0, $company->getCreditUsed() - $amount));
        $this->companyRepo->save($company);
    }
}

Credit Log

namespace Vendor\B2B\Credit\Log;

class CreditLog
{
    public function log(
        int $companyId,
        float $amount,
        int $orderId,
        string $type = 'used'
    ): void {
        $logEntry = new CreditLogData([
            'company_id' => $companyId,
            'amount' => $amount,
            'order_id' => $orderId,
            'type' => $type,
            'created_at' => new \DateTime(),
        ]);

        $this->logRepo->save($logEntry);
    }
}

Quiz

1. What does a company structure define?

Question 1 options

2. What is an approval workflow?

Question 2 options

3. How do credit limits work?

Question 3 options

Flashcards

Question

What is company structure?

Answer

Hierarchical organization of users and teams

Question

What are approval rules?

Answer

Conditions requiring manager approval for orders

Question

What is a credit limit?

Answer

Maximum spending cap for a company account

Question

What are company roles?

Answer

Permission sets assigned to company users

Revision Notes

Key Takeaways

  • 1. Company structure organizes users in hierarchical groups
  • 2. Roles and permissions control user access
  • 3. Approval workflows enforce spending controls
  • 4. Credit limits cap company spending
  • 5. Credit logs track usage and releases

Interview Tips

  • Explain company hierarchy design
  • Discuss approval rule configurations
  • Describe credit limit management
  • Talk about role-based permission systems

Cheat Sheet

Company:
  Structure → hierarchy of groups
  Roles → permission sets
  Users → company members

Approvals:
  Rule → condition matching
  Approvers → designated users
  Workflow → approve/reject flow

Credit:
  Limit → max spending cap
  Used → current balance
  Available → limit - used
  Log → usage history