wizard firm creation
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
{% extends "ui/templates/base/layout.html" %}
|
||||
{% block content %}
|
||||
<div class="mx-auto max-w-4xl">
|
||||
<div class="rounded-3xl border border-emerald-200 bg-white p-6 shadow-soft">
|
||||
<div class="rounded-2xl bg-emerald-50 p-4 text-emerald-800">
|
||||
<h1 class="text-2xl font-semibold">Firm created successfully</h1>
|
||||
<p class="mt-1 text-sm">The tenant, primary branch, Firm Admin and invite token have been created.</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 grid gap-4 md:grid-cols-2">
|
||||
<div class="rounded-2xl border p-4">
|
||||
<div class="text-xs font-semibold uppercase tracking-wide text-slate-500">Firm</div>
|
||||
<div class="mt-2 text-lg font-semibold">{{ tenant.name }}</div>
|
||||
<div class="text-sm text-slate-500">{{ tenant.code }} · {{ tenant.firm_type }}</div>
|
||||
</div>
|
||||
<div class="rounded-2xl border p-4">
|
||||
<div class="text-xs font-semibold uppercase tracking-wide text-slate-500">Primary Branch</div>
|
||||
<div class="mt-2 text-lg font-semibold">{{ branch.name }}</div>
|
||||
<div class="text-sm text-slate-500">{{ branch.code }} · Head Office</div>
|
||||
</div>
|
||||
<div class="rounded-2xl border p-4">
|
||||
<div class="text-xs font-semibold uppercase tracking-wide text-slate-500">Firm Admin</div>
|
||||
<div class="mt-2 text-lg font-semibold">{{ firm_admin.full_name }}</div>
|
||||
<div class="text-sm text-slate-500">{{ firm_admin.email }}</div>
|
||||
</div>
|
||||
<div class="rounded-2xl border p-4">
|
||||
<div class="text-xs font-semibold uppercase tracking-wide text-slate-500">Financial Year</div>
|
||||
{% if financial_year %}
|
||||
<div class="mt-2 text-lg font-semibold">{{ financial_year.year_code }}</div>
|
||||
<div class="text-sm text-slate-500">AY {{ financial_year.assessment_year }}{% if financial_year.is_current %} · Current{% endif %}</div>
|
||||
{% else %}
|
||||
<div class="mt-2 text-sm text-slate-500">Not created from wizard.</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 rounded-2xl border border-brand-200 bg-brand-50 p-4">
|
||||
<div class="text-sm font-semibold text-brand-900">Firm Admin invite link</div>
|
||||
<p class="mt-1 text-xs text-brand-800">Copy and share this link with the Firm Admin. The user will set their password through the invite acceptance page.</p>
|
||||
<div class="mt-3 break-all rounded-xl border border-brand-200 bg-white p-3 text-sm text-brand-900">{{ invite_url }}</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex flex-wrap gap-3">
|
||||
<a href="/wizards/system/firm/new" class="rounded-xl bg-slate-900 px-4 py-2 text-sm font-medium text-white hover:bg-slate-800">Create another firm</a>
|
||||
<a href="/system-settings/tenants" class="rounded-xl border border-slate-300 px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">View firms</a>
|
||||
<a href="/system-settings/users" class="rounded-xl border border-slate-300 px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">View users</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,184 @@
|
||||
{% extends "ui/templates/base/layout.html" %}
|
||||
{% block content %}
|
||||
<div class="max-w-5xl">
|
||||
<div class="flex items-start justify-between gap-4">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold">System Admin · Firm Creation Wizard</h1>
|
||||
<p class="mt-1 text-sm text-slate-500">Create a new firm, primary branch, primary Firm Admin and optional default financial year in one controlled flow.</p>
|
||||
</div>
|
||||
<a href="/system-settings/tenants" class="rounded-xl border border-slate-300 px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">Tenants</a>
|
||||
</div>
|
||||
|
||||
{% if errors %}
|
||||
<div class="mt-4 rounded-2xl border border-red-200 bg-red-50 p-4 text-sm text-red-800">
|
||||
<div class="font-semibold">Please correct the following:</div>
|
||||
<ul class="mt-2 list-disc pl-5">
|
||||
{% for error in errors %}<li>{{ error }}</li>{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form class="mt-5 space-y-5" method="post" action="/wizards/system/firm/preview">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}" />
|
||||
|
||||
<section class="rounded-2xl border bg-white p-5 shadow-soft">
|
||||
<div class="mb-4">
|
||||
<h2 class="text-lg font-semibold">1. Firm details</h2>
|
||||
<p class="text-sm text-slate-500">These are platform-level firm/tenant details controlled by System Admin.</p>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Firm code</span>
|
||||
<input class="rounded-xl border px-3 py-2 uppercase" name="tenant_code" value="{{ form.tenant_code }}" required />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Firm name</span>
|
||||
<input class="rounded-xl border px-3 py-2" name="tenant_name" value="{{ form.tenant_name }}" required />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Firm type</span>
|
||||
<select class="rounded-xl border px-3 py-2" name="firm_type">
|
||||
<option value="partnership" {% if form.firm_type == 'partnership' %}selected{% endif %}>Partnership Firm</option>
|
||||
<option value="proprietorship" {% if form.firm_type == 'proprietorship' %}selected{% endif %}>Proprietorship Firm</option>
|
||||
<option value="individual" {% if form.firm_type == 'individual' %}selected{% endif %}>Individual Audit Practice</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Default timezone</span>
|
||||
<input class="rounded-xl border px-3 py-2" name="default_timezone" value="{{ form.default_timezone or 'Asia/Kolkata' }}" />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Session duration minutes</span>
|
||||
<input class="rounded-xl border px-3 py-2" type="number" min="15" name="default_session_duration_minutes" value="{{ form.default_session_duration_minutes or 480 }}" />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Storage mode</span>
|
||||
<select class="rounded-xl border px-3 py-2" name="default_storage_mode">
|
||||
<option value="local_only" {% if form.default_storage_mode == 'local_only' %}selected{% endif %}>local_only</option>
|
||||
<option value="cloud_only" {% if form.default_storage_mode == 'cloud_only' %}selected{% endif %}>cloud_only</option>
|
||||
<option value="hybrid" {% if form.default_storage_mode == 'hybrid' %}selected{% endif %}>hybrid</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="grid gap-1 md:col-span-2">
|
||||
<span class="text-sm text-slate-600">OTP required roles CSV</span>
|
||||
<input class="rounded-xl border px-3 py-2" name="default_otp_required_roles_csv" value="{{ form.default_otp_required_roles_csv or 'Partner,System Admin' }}" />
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="rounded-2xl border bg-white p-5 shadow-soft">
|
||||
<div class="mb-4">
|
||||
<h2 class="text-lg font-semibold">2. Primary branch</h2>
|
||||
<p class="text-sm text-slate-500">The wizard creates the head office branch and basic branch settings.</p>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Branch code</span>
|
||||
<input class="rounded-xl border px-3 py-2 uppercase" name="branch_code" value="{{ form.branch_code or 'HO' }}" required />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Branch name</span>
|
||||
<input class="rounded-xl border px-3 py-2" name="branch_name" value="{{ form.branch_name or 'Head Office' }}" required />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Branch timezone</span>
|
||||
<input class="rounded-xl border px-3 py-2" name="branch_timezone" value="{{ form.branch_timezone or form.default_timezone or 'Asia/Kolkata' }}" />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">State</span>
|
||||
<input class="rounded-xl border px-3 py-2" name="branch_state" value="{{ form.branch_state }}" />
|
||||
</label>
|
||||
<label class="grid gap-1 md:col-span-2">
|
||||
<span class="text-sm text-slate-600">Address line 1</span>
|
||||
<input class="rounded-xl border px-3 py-2" name="branch_address_line1" value="{{ form.branch_address_line1 }}" />
|
||||
</label>
|
||||
<label class="grid gap-1 md:col-span-2">
|
||||
<span class="text-sm text-slate-600">Address line 2</span>
|
||||
<input class="rounded-xl border px-3 py-2" name="branch_address_line2" value="{{ form.branch_address_line2 }}" />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">City</span>
|
||||
<input class="rounded-xl border px-3 py-2" name="branch_city" value="{{ form.branch_city }}" />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">PIN code</span>
|
||||
<input class="rounded-xl border px-3 py-2" name="branch_pin_code" value="{{ form.branch_pin_code }}" />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Branch PAN</span>
|
||||
<input class="rounded-xl border px-3 py-2 uppercase" name="branch_pan" value="{{ form.branch_pan }}" />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Branch GSTIN</span>
|
||||
<input class="rounded-xl border px-3 py-2 uppercase" name="branch_gstin" value="{{ form.branch_gstin }}" />
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="rounded-2xl border bg-white p-5 shadow-soft">
|
||||
<div class="mb-4">
|
||||
<h2 class="text-lg font-semibold">3. Primary Firm Admin</h2>
|
||||
<p class="text-sm text-slate-500">This user gets the Firm Admin role and an invite link to set password.</p>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Full name</span>
|
||||
<input class="rounded-xl border px-3 py-2" name="admin_full_name" value="{{ form.admin_full_name }}" required />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Email</span>
|
||||
<input class="rounded-xl border px-3 py-2" type="email" name="admin_email" value="{{ form.admin_email }}" required />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Mobile</span>
|
||||
<input class="rounded-xl border px-3 py-2" name="admin_mobile" value="{{ form.admin_mobile }}" />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Designation</span>
|
||||
<input class="rounded-xl border px-3 py-2" name="admin_designation" value="{{ form.admin_designation or 'Firm Admin' }}" />
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="rounded-2xl border bg-white p-5 shadow-soft">
|
||||
<div class="mb-4 flex items-start justify-between gap-4">
|
||||
<div>
|
||||
<h2 class="text-lg font-semibold">4. Default financial year</h2>
|
||||
<p class="text-sm text-slate-500">Optional. Firm Admin can also manage financial years later from System Settings.</p>
|
||||
</div>
|
||||
<label class="flex items-center gap-2 text-sm font-medium text-slate-700">
|
||||
<input type="checkbox" name="create_financial_year" {% if form.create_financial_year %}checked{% endif %} />
|
||||
Create FY
|
||||
</label>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Financial year code</span>
|
||||
<input class="rounded-xl border px-3 py-2" name="fy_year_code" value="{{ form.fy_year_code }}" placeholder="2026-27" />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Assessment year</span>
|
||||
<input class="rounded-xl border px-3 py-2" name="fy_assessment_year" value="{{ form.fy_assessment_year }}" placeholder="2027-28" />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">Start date</span>
|
||||
<input class="rounded-xl border px-3 py-2" type="date" name="fy_start_date" value="{{ form.fy_start_date }}" />
|
||||
</label>
|
||||
<label class="grid gap-1">
|
||||
<span class="text-sm text-slate-600">End date</span>
|
||||
<input class="rounded-xl border px-3 py-2" type="date" name="fy_end_date" value="{{ form.fy_end_date }}" />
|
||||
</label>
|
||||
<label class="flex items-center gap-2 text-sm font-medium text-slate-700">
|
||||
<input type="checkbox" name="fy_is_current" {% if form.fy_is_current %}checked{% endif %} />
|
||||
Mark as current financial year
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="flex gap-3">
|
||||
<button class="rounded-xl bg-slate-900 px-5 py-2.5 text-sm font-medium text-white hover:bg-slate-800" type="submit">Preview Firm Creation</button>
|
||||
<a class="rounded-xl border border-slate-300 px-5 py-2.5 text-sm font-medium text-slate-700 hover:bg-slate-50" href="/system-settings">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,76 @@
|
||||
{% extends "ui/templates/base/layout.html" %}
|
||||
{% block content %}
|
||||
<div class="max-w-5xl">
|
||||
<h1 class="text-2xl font-semibold">Preview Firm Creation</h1>
|
||||
<p class="mt-1 text-sm text-slate-500">Review the details. Nothing is saved until you click Confirm.</p>
|
||||
|
||||
<form class="mt-5" method="post" action="/wizards/system/firm/confirm">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}" />
|
||||
{% for key, value in form.items() %}
|
||||
{% if value is sameas true %}
|
||||
<input type="hidden" name="{{ key }}" value="on" />
|
||||
{% elif value is not sameas false and value is not none %}
|
||||
<input type="hidden" name="{{ key }}" value="{{ value }}" />
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<div class="grid gap-5 lg:grid-cols-2">
|
||||
<section class="rounded-2xl border bg-white p-5 shadow-soft">
|
||||
<h2 class="text-lg font-semibold">Firm</h2>
|
||||
<dl class="mt-4 space-y-2 text-sm">
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">Code</dt><dd class="font-medium">{{ form.tenant_code }}</dd></div>
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">Name</dt><dd class="font-medium">{{ form.tenant_name }}</dd></div>
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">Type</dt><dd class="font-medium">{{ form.firm_type }}</dd></div>
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">Timezone</dt><dd class="font-medium">{{ form.default_timezone }}</dd></div>
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">Storage</dt><dd class="font-medium">{{ form.default_storage_mode }}</dd></div>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section class="rounded-2xl border bg-white p-5 shadow-soft">
|
||||
<h2 class="text-lg font-semibold">Primary Branch</h2>
|
||||
<dl class="mt-4 space-y-2 text-sm">
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">Code</dt><dd class="font-medium">{{ form.branch_code }}</dd></div>
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">Name</dt><dd class="font-medium">{{ form.branch_name }}</dd></div>
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">City / State</dt><dd class="font-medium">{{ form.branch_city or '-' }}{% if form.branch_state %}, {{ form.branch_state }}{% endif %}</dd></div>
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">PAN</dt><dd class="font-medium">{{ form.branch_pan or '-' }}</dd></div>
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">GSTIN</dt><dd class="font-medium">{{ form.branch_gstin or '-' }}</dd></div>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section class="rounded-2xl border bg-white p-5 shadow-soft">
|
||||
<h2 class="text-lg font-semibold">Primary Firm Admin</h2>
|
||||
<dl class="mt-4 space-y-2 text-sm">
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">Name</dt><dd class="font-medium">{{ form.admin_full_name }}</dd></div>
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">Email</dt><dd class="font-medium">{{ form.admin_email }}</dd></div>
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">Mobile</dt><dd class="font-medium">{{ form.admin_mobile or '-' }}</dd></div>
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">Role</dt><dd class="font-medium">Firm Admin</dd></div>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section class="rounded-2xl border bg-white p-5 shadow-soft">
|
||||
<h2 class="text-lg font-semibold">Financial Year</h2>
|
||||
{% if form.create_financial_year %}
|
||||
<dl class="mt-4 space-y-2 text-sm">
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">FY</dt><dd class="font-medium">{{ form.fy_year_code }}</dd></div>
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">AY</dt><dd class="font-medium">{{ form.fy_assessment_year }}</dd></div>
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">Dates</dt><dd class="font-medium">{{ form.fy_start_date }} to {{ form.fy_end_date }}</dd></div>
|
||||
<div class="flex justify-between gap-4"><dt class="text-slate-500">Current</dt><dd class="font-medium">{{ 'Yes' if form.fy_is_current else 'No' }}</dd></div>
|
||||
</dl>
|
||||
{% else %}
|
||||
<p class="mt-4 text-sm text-slate-500">No financial year will be created now.</p>
|
||||
{% endif %}
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="mt-5 rounded-2xl border border-amber-200 bg-amber-50 p-4 text-sm text-amber-900">
|
||||
Confirming will create the tenant, head office branch, Firm Admin user, invite token and optional financial year.
|
||||
</div>
|
||||
|
||||
<div class="mt-5 flex gap-3">
|
||||
<button class="rounded-xl bg-slate-900 px-5 py-2.5 text-sm font-medium text-white hover:bg-slate-800" type="submit">Confirm & Create Firm</button>
|
||||
<button class="rounded-xl border border-slate-300 px-5 py-2.5 text-sm font-medium text-slate-700 hover:bg-slate-50" type="button" onclick="history.back()">Back to Edit</button>
|
||||
<a class="rounded-xl border border-slate-300 px-5 py-2.5 text-sm font-medium text-slate-700 hover:bg-slate-50" href="/system-settings">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user