WAW Group Global

Loading form...

Request Received

Thank you. Our team has been notified and will be in touch.

Your reference

{{ publicSubmittedRef }}

{{ publicError }}

Submitted details are used only to handle your request.

WAW Group Global · Accounts Management

WAW Group Global

Loading your form...

Link Unavailable

{{ approvalError }}

Thank You

Your approval has been received and passed to our team. There's nothing more you need to do.

Prepared for

{{ approvalDispatch.clientName }}

{{ approvalError }}

By approving, you confirm these details are correct for our team to proceed.

WAW Group Global · Accounts Management

Loading AMS Portal

Preparing secure workspace...

Logo

Gateway Access

INTERNAL PERSONNEL ENTRY

{{ authError }}
{{ unreadNotificationsCount }}

Notifications

{{ pushError }}

Desktop alerts fire while AMS is open in a tab, including minimised. Push reaches you with AMS fully closed — on iPhone, add AMS to your Home Screen first.

No notifications

{{ notification.title }}
{{ notification.action }}
{{ notification.message }}
{{ notification.actor }}
{{ formatDate(notification.timestamp) }}
{{ currentUser?.displayName || currentUser?.email?.split('@')[0] }}
{{ (currentUser?.displayName || currentUser?.email || 'U').charAt(0).toUpperCase() }}
Team Meeting Ongoing Join Now

Account Hub

{{ activeClients.length }}

+{{ sunsetClientCount }} sunset

Overdue

{{ getTaskCountByUrgency('Overdue') }}

Urgent Pipeline

{{ getTaskCountByUrgency('Urgent') }}

{{ currentUserRole === 'Admin' ? 'Collected YTD' : 'Collected WTD' }}

£{{ currentUserRole === 'Admin' ? calculatePaidInvoicesYTD() : calculatePaidInvoicesWTD() }}

Pipeline Eff.

{{ calculatePipelineEfficiency() }}%

Live Team Attendance

Live Real-Time
StaffCurrent StatusStatus DurationTotal Productive
{{ getStaffName(shift.userId) }} {{ shift.status }} {{ shift.durationDisplay }} {{ formatSecondsToTime(shift.totalWorkSeconds || 0) }}
No active staff shifts found right now.

Attendance & Productivity

Live Team Performance Metrics

Live Team Capacity

{{ liveCapacityPercentage }}% {{ activeStaffCount }} Active
{{ metric.initial }}

{{ metric.name }}

{{ metric.totalProdHours }}H Prod.

No attendance data for this period.

Cumulative Productive Hours (Uptick)

Time Analysis (Session Duration)

Financial Health (Inv Count)

Urgency Analysis (Deadlines)

Workflow Capacity (Total Active)

Staff Productivity (Breakdown)

Recent Task Operations

{{ formatDate(log.createdAt) }}

{{ log.action }}

{{ log.context }}

Op: {{ log.staffName }}

No task activity recorded.

Staff Activity Feed

{{ formatDate(log.createdAt) }}

{{ log.action }}

{{ log.context }}

Staff: {{ log.staffName }}

No recent shift activity.
Showing {{ filteredClients.length }} account(s)
Account NameStatusAccount HandlerPhoneActive HMRC ServicesCompleted WorkDocsActions
{{ client.name }}
{{ client.company || 'Private' }}
{{ isSunsetClient(client) ? 'Sunset' : 'Active' }}
Retired {{ formatDeadline(client.sunsetAt) }}
{{ getStaffName(client.accountHandlerId) }} {{ client.phone || '—' }}
{{ s.serviceType }}
{{ getClientCompletedTasks(client.id).length }} Tasks Done {{ getClientCompletedTasks(client.id).map(t => t.serviceType).join(', ') || 'No history' }}
Page {{ clientCurrentPage }} of {{ clientTotalPages }}

Compliance Pipeline

Recurring statutory obligations only. Ad-hoc work lives in , inbound work in .

{{ compliancePipeline.length }} open

Overdue

{{ countByUrgency(compliancePipeline, 'Overdue') }}

Urgent (<= 2d)

{{ countByUrgency(compliancePipeline, 'Urgent') }}

Due (3-15d)

{{ countByUrgency(compliancePipeline, 'Pending') }}

Upcoming (16d+)

{{ countByUrgency(compliancePipeline, 'Upcoming') }}

Pipeline Clear

No compliance tasks match the current filters.

Client Service / Period Deadline Internal Status Personnel Action
{{ getTaskDisplayName(task) }}
Handler: {{ getStaffName(getClient(task.clientId).accountHandlerId) }}
{{ task.serviceType }}
{{ periodKeyLabel(task.periodKey) }}
{{ formatDeadline(task.filingDeadline) }}
{{ deadlineDistanceLabel(task) }}
{{ formatDeadline(task.internalDeadline) }} {{ task.status }} {{ getTaskPriority(task) }} {{ getStaffName(task.assigneeId) }}
Page {{ taskCurrentPage }} of {{ taskTotalPages }}

Admin Tasks

Internal one-off work. These never recur and are completed permanently.

Overdue

{{ countByUrgency(adminTasks, 'Overdue') }}

Urgent

{{ countByUrgency(adminTasks, 'Urgent') }}

Unassigned

{{ adminTasks.filter(t => !t.assigneeId).length }}

Total Open

{{ adminTasks.length }}

{{ col.label }}
{{ col.overdue }} {{ col.total }}
{{ col.from }}–{{ col.to }} of {{ col.total }}
{{ getTaskDisplayName(task) }} {{ getTaskPriority(task) }}

{{ task.serviceType }}

{{ task.description }}

{{ formatDeadline(task.filingDeadline) }}

{{ deadlineDistanceLabel(task) }}

{{ staffInitials(task.assigneeId) }}

Drop here

No Admin Tasks

Nothing matches the current filters.

{{ task.serviceType }}

{{ getTaskDisplayName(task) }} · {{ task.description }}

{{ staffInitials(task.assigneeId) }}
Client Task Due Priority Status Assigned Action
{{ getTaskDisplayName(task) }}
{{ task.serviceType }}
{{ task.description }}
{{ formatDeadline(task.filingDeadline) }}
{{ deadlineDistanceLabel(task) }}
{{ getTaskPriority(task) }} {{ task.status }} {{ task.assigneeId ? getStaffName(task.assigneeId) : 'Unassigned' }}
Page {{ adminTaskCurrentPage }} of {{ adminTaskTotalPages }}

Client Requests

Inbound submissions from the public request form. Match each one to an account, then turn it into work.

{{ untriagedRequestCount }} awaiting triage

Share this with clients

{{ publicRequestUrl }}

No login required

Awaiting Client Approval

Sent for approval {{ formatDeadline(d.createdAt) }}

{{ d.formTitle }}

{{ d.clientName }} · sent by {{ d.createdByName }}

When a client approves, an Admin Task is created automatically.

New Submissions

{{ req.refCode }} {{ req.linkedClientId ? 'Linked' : 'Unmatched' }}

{{ req.subject }}

{{ req.name }} · {{ req.company }}

{{ formatDeadline(req.submittedAt) }}

{{ req.email }}

{{ req.phone }}

DOB: {{ req.dob }}

{{ req.detail }}

{{ answer.label }}

{{ formatRequestAnswer(answer.value) }}

Account
{{ requestErrors[req.id] }}

In Progress

{{ task.serviceType }}

{{ getTaskDisplayName(task) }}

{{ task.status }}
Due {{ formatDeadline(task.filingDeadline) }} {{ task.attachments.length }}
Page {{ requestCurrentPage }} of {{ requestTotalPages }}

Inbox Clear

Nothing waiting. New submissions from the request form land here.

Recurring Schedules

Each schedule generates one Compliance Pipeline task per period. Filed periods are kept permanently.

No Schedules

Schedules are created automatically when you assign a service to a client, or add one manually.

Client Service Frequency Next Due Filed State Action
{{ getClientName(sch.clientId) }}
{{ sch.serviceType }} {{ FREQUENCY_LABELS[sch.frequency] || sch.frequency }} {{ formatJsDate(scheduleNextDue(sch)) }} {{ scheduleFiledCount(sch) }} {{ sch.active === false ? 'Paused' : 'Active' }}
Page {{ scheduleCurrentPage }} of {{ scheduleTotalPages }}

Monthly Targets

Set what each client should get this month. Progress is read live from the Compliance Pipeline and Admin Tasks — targets never hold their own copy of the work.

Target Month

{{ monthKeyLabel(targetMonth) }}

Month delivered {{ targetSummary.percent }}%

Targets Set

{{ targetSummary.total }}

Complete

{{ targetSummary.complete }}

At Risk

{{ targetSummary.atRisk }}

Missed

{{ targetSummary.missed }}

No Targets for {{ monthKeyLabel(targetMonth) }}

Set a target to commit to a piece of work for a client this month. Matching tasks in the pipeline light it up automatically.

Client Service Deadline Owner Progress State Actions
{{ getClientName(t.clientId) }}
{{ getClient(t.clientId)?.company || 'Private' }}
Client sunset
{{ t.serviceType }}
{{ formatDeadline(t.deadline) }}
{{ deadlineDistanceLabel({ filingDeadline: t.deadline }) }}
{{ t.assigneeId ? getStaffName(t.assigneeId) : 'Unassigned' }}
{{ targetProgress(t).filed }}/{{ targetProgress(t).total }} filed {{ targetProgress(t).percent }}%

No matching work yet.

{{ t.notes }}

{{ targetState(t) }}

Completed Tasks Archive

Review filed and completed assignments per individual.

Client Account Task / Service Type Date Completed Action
{{ task.clientName }} {{ task.taskName }} {{ task.type }} {{ formatDate(task.dateCompleted) }} Archived
Please select a staff member above to view history.
No completed tasks found for this timeframe.

Time Recorder

Professional Time Tracking

{{ new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) }}
{{ shiftState.status === 'Offline' || shiftState.status === 'Ended' ? 'Shift Ended' : shiftState.status }}
{{ shiftElapsedTime }}
Current Status Duration

Shift Totals

Productive Time
{{ formatSecondsToTime(liveProductiveTime) }}
Clock In
{{ shiftState.startTime ? formatDateOnlyTime(shiftState.startTime) : '--:--' }}

Activity Log

TimeEvent
{{ formatDateOnlyTime(log.timestamp) }}{{ log.type }}

Team Workload Distribution

Active Task Allocation Per Staff Member

{{ data.member.name.charAt(0) }}

{{ data.member.name }}

{{ data.member.role }}

{{ data.activeTasks.length }}

Active Tasks

Pending

{{ data.stats.pending }}

In Progress

{{ data.stats.inProgress }}

Auditing

{{ data.stats.auditing }}

Filed

{{ data.stats.filed }}

{{ getTaskDisplayName(task) }}

{{ task.serviceType }}

Handler Oversight

{{ getTaskUrgency(task) }}
No active priority assignments.

Staff Schedule Monitor

Detailed Time Estimation & Completion Status

{{ member.name.charAt(0) }}

{{ member.name }}

{{ member.role }}

Active Assignments

{{ getMemberTasks(member.id).length }}

Task Details Schedule (Est. vs Actual) Percentage Completion Efficiency
{{ getTaskDisplayName(task) }}
{{ task.serviceType }}

Target

{{ task.estimatedHours || 0 }}h

Actual

{{ formatSecondsToHours(task.timeSpent) }}

{{ task.completionPercentage || 0 }}% Done
No Estimate Set
On Track Over Time
No active tasks scheduled for {{ member.name.split(' ')[0] }}.
{{ (currentUser?.displayName || currentUser?.email || 'U').charAt(0).toUpperCase() }}

My Assignments

Focus Mode • {{ myPersonalTasks.length }} Active Tasks

ClientServiceDeadlineStatusAction
{{ getTaskDisplayName(task) }}
Oversight (Assigned to: {{ getStaffName(task.assigneeId) }})
{{ task.serviceType }}{{ formatDate(task.filingDeadline) }}{{ task.status }}
No tasks currently assigned to you.

Monthly Target

£ {{ monthlyTarget.toLocaleString() }}

Awaiting funds (Total)

£{{ calculatePendingInvoices() }}

Awaiting funds (WTD)

£{{ calculatePendingInvoicesWTD() }}

Overdue (Arrears)

£{{ calculateOverdueInvoices() }}

Collected Revenue (YTD)

£{{ calculatePaidInvoicesYTD() }}

Collected Revenue (WTD)

£{{ calculatePaidInvoicesWTD() }}

Weekly Target

£{{ weeklyTarget.toLocaleString() }}
Serial Account Profile Net Value Status Control
{{ inv.invoiceNumber || inv.id }}
{{ inv.clientName }}
Due: {{ formatDate(inv.date) }} (Overdue)
£{{ (parseFloat(inv.amount) || 0).toFixed(2) }} {{ inv.status || 'Draft' }}
No invoices found matching current filters.
Page {{ invoiceCurrentPage }} of {{ invoiceTotalPages }}

Staff Shift Management

Admin Control Panel

{{ new Date().toLocaleDateString() }}

{{ staff.name }}

{{ staff.role }}

{{ staff.status }}
{{ staff.durationDisplay }}

Current Status Duration

Prod: {{ formatSecondsToTime(staff.liveTotalProductive) }} In: {{ formatDateOnlyTime(staff.shift.startTime) }}

Practice Reporting

Live figures across the whole practice. Derived from data already loaded — reading this page costs nothing.

Open Work

{{ reportKpis.open }}

Overdue

{{ reportKpis.overdue }}

Unassigned

{{ reportKpis.unassigned }}

Filed / {{ reportPeriodLabel }}

{{ reportKpis.filed }}

Avg Turnaround

{{ reportNum(reportKpis.avgTurnaround, 'd') }}

Filed On Time

{{ reportNum(reportKpis.onTime, '%') }}

Completed-work figures cover the most recent 150 filings only — that cap is deliberate, and keeps your Firestore read costs down. {{ reportCoverage.undated }} filed task(s) predate completion timestamps, so they are excluded from turnaround and on-time figures.

Throughput

Tasks filed per month

{{ m.count || '' }}
{{ m.label }}

Overdue Ageing

How long missed deadlines have been sitting

{{ b.label }} {{ b.count }}

Open Work by Type

{{ k.label }} {{ k.open }} {{ k.pct }}%

Staff Scorecard

Open load now, plus everything filed in the selected window

Staff Open Overdue Filed Avg Days On Time
{{ staffInitials(r.id) }} {{ r.name }}
{{ r.open }} {{ r.overdue }} {{ r.filed }} {{ reportNum(r.avgTurnaround, 'd') }} {{ reportNum(r.onTime, '%') }}
No activity in this window.

By Service Line

Sorted by overdue exposure

Service Open Overdue Filed Avg
{{ r.name }} {{ r.open }} {{ r.overdue }} {{ r.filed }} {{ reportNum(r.avgTurnaround, 'd') }}
Nothing to report.

Client Exposure

Top 10 accounts by outstanding work

Account Open Overdue
{{ r.name }} {{ r.open }} {{ r.overdue }}
No open work.

Raw Data Exports

For spreadsheets, pivot tables and third-party systems

Personnel Directory

Manage team access and system roles.

PersonnelSystem AccessEnrolled SinceControl
{{ user.name }}
{{ user.email }}
{{ user.role }} {{ formatDate(user.createdAt) }}

Audit Trail

System-wide operations and tracking.

PersonnelOperationContextTimestamp
{{ log.staffName }} {{ log.action }} {{ log.context }} {{ formatDate(log.createdAt) }}
No activity logs found for this selection.
Page {{ auditCurrentPage }} of {{ auditTotalPages }}

Message sync problem

{{ chatError }}

Calling unavailable

{{ callSystemError }} Paste the updated firestore.rules into Firebase Console → Firestore Database → Rules. Chat is unaffected.

Messages

{{ availableChats.find(c => c.id === activeChatId)?.name || 'Select a chat' }}

Secure End-to-End Connection

Loading earlier messages...

Showing the most recent {{ chatMessages.length }} messages. Older history is not loaded to keep the database reads down.

Beginning of conversation

{{ msg.senderName }} • {{ formatDateOnlyTime(msg.timestamp) }} - {{ formatDate(msg.timestamp).split(',')[0] }}
Message removed {{ msg.text }} {{ msg.fileName }}
{{ getSeenText(msg, availableChats.find(c => c.id === activeChatId)?.type) }}
No messages yet. Start the conversation!

System Notifications

Enter your Google Chat Incoming Webhook URL here.

Daily · in-app calls

Calling a teammate rings them inside AMS and opens a private, single-use room in a floating panel — no new tab and no third-party sign-in. A fresh room is created for every call and expires afterwards, so links can never be reused.

Nothing to configure. The API credential lives as an encrypted Cloudflare environment variable and never reaches the browser.

{{ dailySdkReady ? 'In-app calling ready' : 'In-app calling unavailable' }}

The Daily video SDK did not load in this browser, so calls will open in a new tab instead of the floating panel. An ad-blocker, privacy extension or network policy blocking unpkg.com is the usual cause — allow it for this site and reload.

Calls will open in the floating panel inside AMS.

Email provider

Assignees, the person who raised the item, and every administrator are emailed when a task is assigned, when its status changes, when a deadline is close or missed, and when a client requests a call.

Email alerts are not sending

{{ emailAlertError }}

The sending credential lives as an encrypted Cloudflare environment variable and never reaches the browser. A problem with sending will be reported here.

Alerts never go to the person who caused them. If you are the assignee, the person who raised it and the only administrator, a real action emails nobody at all — so use this to test.

{{ emailTestResult }}

Most recent alert

{{ lastEmailOutcome }}

No email address on file

{{ staffMissingEmail.join(', ') }} — these people are skipped by every email alert. Add an address on their record in Personnel.

Deadline reminders

A deadline is counted down over the five days before it lands — in 5 days, in 4 days, down to tomorrow and today — then daily once it is late.

Once more than 10 tasks are in either group, the individual emails stop and one digest goes to administrators instead, naming the total and the worst offender. Forty late tasks should not mean forty emails.

Swept hourly from an open AMS session, so it needs somebody to have AMS open that day. Each task raises at most one email per day however many people are signed in.

End-of-week report

Every Friday, administrators get one email covering the week: how many actions were recorded, what was completed, what is open and overdue, a breakdown by type of work, and how much each person did.

Counted from the audit trail rather than the task lists, so a busy week is not under-reported. If nobody opens AMS on the Friday, the report is sent on the next day someone does — it is delayed, never skipped.

Play each cue on demand, without waiting for a message or placing a call. If these are silent the problem is your volume, your browser, or the mute toggle in the header — not AMS.

{{ soundEnabled ? 'Alert sounds are on.' : 'Alert sounds are MUTED — nothing will play until you unmute using the speaker icon in the header.' }}

Requested Calls

Clients who have asked to speak to someone. Log the request when it comes in, then close it out once the call has happened.

Waiting on you

{{ myCallRequests.length }} {{ myCallRequests.length === 1 ? 'client is' : 'clients are' }} waiting for a call from you.

No open call requests

{{ req.urgency || 'Routine' }} {{ req.status }} Logged {{ formatDate(req.createdAt) }} by {{ req.createdByName }}

{{ req.clientName }}

for {{ req.requestedForName }}

{{ req.reason }}

{{ req.contactName }}

{{ req.contactNumber }}

{{ req.preferredTime }}

Client Form Builder

Select a form to fill in and send to a client, or create a new one.

No forms yet

{{ form.title }}

{{ form.questions?.length || 0 }} questions

{{ form.active !== false ? 'Active' : 'Inactive' }}

Fill & Send to Client

Select a form on the left to pre-fill it and send an approval link to a client.

System Confirmation

{{ notification }}

Set Your Password

You signed in with a temporary password set by your administrator. Choose your own to continue.

{{ passwordChangeError }}

At least 8 characters. Use a mix of letters, numbers and symbols.

{{ confirmDialog.title }}

{{ confirmDialog.message }}

Gateway Access

{{ authBusyMessage }}

Please wait

{{ busyMessage || 'Saving changes...' }}

Shift Check-In

Please confirm your attendance to access the portal workspace.

Current Time

{{ new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}) }}

Update available

A newer version of AMS is live. This tab will update itself as soon as you are not in the middle of something — or take it now.

{{ (callPanelPeer || '?').charAt(0).toUpperCase() }}

{{ callPanelPeer }}

Connecting {{ callDuration }}

{{ callPanelError }}

Starting audio

{{ (incomingCall.fromName || '?').charAt(0).toUpperCase() }}

Incoming call

{{ incomingCall.fromName }}

Answering opens the meeting room in a new tab.

{{ (outgoingCall.toName || '?').charAt(0).toUpperCase() }}

Calling

{{ outgoingCall.toName }}

Their AMS will ring for {{ 45 }} seconds. The room opens automatically when they answer.

Join the room now