Cases add/edit should be working now. Along with the hearings in it

This commit is contained in:
2021-01-18 09:00:30 +05:30
parent 8845ee6a81
commit 8fe385e601
17 changed files with 1013 additions and 420 deletions

View File

@ -251,13 +251,13 @@ def upgrade():
sa.Column("old_id", sa.Integer(), nullable=False),
sa.Column("case_id", postgresql.UUID(as_uuid=True), nullable=True),
sa.Column("old_case_id", sa.Integer(), nullable=False),
sa.Column("judges", sa.Unicode(length=255), nullable=True),
sa.Column("brief", sa.Unicode(length=2000), nullable=True),
sa.Column("court_number", sa.Unicode(length=255), nullable=True),
sa.Column("item_number", sa.Unicode(length=255), nullable=True),
sa.Column("bench", sa.Unicode(length=255), nullable=True),
sa.Column("proceedings", sa.Unicode(length=2000), nullable=True),
sa.Column("next_hearing_date", sa.DateTime(), nullable=True),
sa.Column("court_status_id", postgresql.UUID(as_uuid=True), nullable=True),
sa.Column("old_court_status_id", sa.Integer(), nullable=True),
sa.Column("court_number", sa.Unicode(length=255), nullable=True),
sa.Column("item_number", sa.Unicode(length=255), nullable=True),
sa.ForeignKeyConstraint(["case_id"], ["cases.id"], name=op.f("fk_hearings_case_id_cases")),
sa.ForeignKeyConstraint(
["court_status_id"], ["court_statuses.id"], name=op.f("fk_hearings_court_status_id_court_statuses")

View File

@ -1,6 +1,7 @@
import uuid
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Unicode, text
from luthor.models.hearing import Hearing
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Unicode, desc, text
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
from sqlalchemy.sql import expression
@ -60,6 +61,7 @@ class Case(Base):
office_status = relationship("OfficeStatus")
court_status = relationship("CourtStatus", back_populates="cases")
case_source = relationship("CaseSource", back_populates="cases")
hearings = relationship("Hearing", order_by=desc(Hearing.next_hearing_date), back_populates="case")
def __init__(
self,
@ -94,6 +96,7 @@ class Case(Base):
court_status_id=None,
case_source_id=None,
is_deleted=None,
hearings=None,
id_=None,
):
self.office_file_number = office_file_number
@ -127,4 +130,6 @@ class Case(Base):
self.court_status_id = court_status_id
self.is_deleted = False if is_deleted is None else is_deleted
self.case_source_id = case_source_id
if hearings is not None:
self.hearings = hearings
self.id = id_

View File

@ -20,27 +20,32 @@ class Hearing(Base):
nullable=False,
index=True,
)
judges = Column("judges", Unicode(255), nullable=False, unique=True)
brief = Column("brief", Unicode(255), nullable=False, unique=True)
next_hearing_date = Column("next_hearing_date", DateTime, nullable=False, index=True)
court_status_id = Column("court_status_id", UUID(as_uuid=True), ForeignKey("court_statuses.id"), nullable=True)
court_number = Column("court_number", Unicode(255), nullable=False, unique=True)
item_number = Column("item_number", Unicode(255), nullable=False, unique=True)
bench = Column("bench", Unicode(255), nullable=False, unique=True)
proceedings = Column("proceedings", Unicode(255), nullable=False, unique=True)
next_hearing_date = Column("next_hearing_date", DateTime, nullable=False, index=True)
court_status_id = Column("court_status_id", UUID(as_uuid=True), ForeignKey("court_statuses.id"), nullable=True)
court_status = relationship("CourtStatus", back_populates="hearings")
case = relationship("Case", back_populates="hearings")
def __init__(
self,
voucher_id=None,
code=None,
food_table_id=None,
date=None,
user_id=None,
case_id=None,
court_number=None,
item_number=None,
bench=None,
proceedings=None,
next_hearing_date=None,
court_status_id=None,
id_=None,
):
self.id = id_
self.voucher_id = voucher_id
self.code = code
self.food_table_id = food_table_id
self.date = date
self.user_id = user_id
self.case_id = case_id
self.court_number = court_number
self.item_number = item_number
self.bench = bench
self.proceedings = proceedings
self.next_hearing_date = next_hearing_date
self.court_status_id = court_status_id

View File

@ -7,6 +7,7 @@ import luthor.schemas.case as schemas
from fastapi import APIRouter, Depends, HTTPException, Security, status
from luthor.models.case_source import CaseSource
from luthor.models.hearing import Hearing
from sqlalchemy import desc, func
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session
@ -37,6 +38,7 @@ def save(
) -> schemas.Case:
try:
item = Case(
case_source_id=data.case_source.id_,
office_file_number=data.office_file_number,
court_case_number=data.court_case_number,
year=data.year,
@ -66,6 +68,17 @@ def save(
nature_id=data.nature.id_ if data.nature is not None else None,
office_status_id=data.office_status.id_ if data.office_status is not None else None,
court_status_id=data.court_status.id_ if data.court_status is not None else None,
hearings=[
Hearing(
court_number=h.court_number,
item_number=h.item_number,
bench=h.bench,
proceedings=h.proceedings,
next_hearing_date=h.next_hearing_date,
court_status_id=h.court_status.id_ if h.court_status is not None else None,
)
for h in data.hearings
],
)
db.add(item)
db.commit()
@ -90,6 +103,7 @@ def update(
) -> schemas.Case:
try:
item: Case = db.query(Case).filter(Case.id == id_).first()
item.case_source_id = data.case_source.id_,
item.office_file_number = data.office_file_number
item.court_case_number = data.court_case_number
item.year = data.year
@ -119,6 +133,36 @@ def update(
item.nature_id = data.nature.id_ if data.nature is not None else None
item.office_status_id = data.office_status.id_ if data.office_status is not None else None
item.court_status_id = data.court_status.id_ if data.court_status is not None else None
old_ids = set(h.id for h in item.hearings)
new_ids = set(h.id_ for h in data.hearings if h.id_ is not None)
# Delete removed
for ids in old_ids - new_ids:
h: Hearing = next(x for x in item.hearings if x.id == ids)
db.delete(h)
item.hearings.remove(h)
# Update Common
for ids in old_ids & new_ids:
h: Hearing = next(x for x in item.hearings if x.id == ids)
d: schemas.Hearing = next(x for x in data.hearings if x.id_ == ids)
h.court_number = d.court_number
h.item_number = d.item_number
h.bench = d.bench
h.proceedings = d.proceedings
h.next_hearing_date = d.next_hearing_date
h.court_status_id = d.court_status.id_ if d.court_status is not None else None
for d in [d for d in data.hearings if d.id_ is None]:
h = Hearing(
court_number=d.court_number,
item_number=d.item_number,
bench=d.bench,
proceedings=d.proceedings,
next_hearing_date=d.next_hearing_date,
court_status_id=d.court_status.id_ if d.court_status is not None else None,
)
item.hearings.append(h)
db.add(h)
db.commit()
return case_info(item)
except SQLAlchemyError as e:
@ -243,6 +287,20 @@ def case_info(item: Case) -> schemas.Case:
courtStatus=schemas.CourtStatusLink(id=item.court_status.id, name=item.court_status.name)
if item.court_status is not None
else None,
hearings=[
schemas.Hearing(
id=h.id,
courtNumber=h.court_number if h.court_number is not None else "",
itemNumber=h.item_number if h.item_number is not None else "",
bench=h.bench if h.bench is not None else "",
proceedings=h.proceedings if h.proceedings is not None else "",
nextHearingDate=h.next_hearing_date,
courtStatus=schemas.CourtStatusLink(id=h.court_status.id, name=h.court_status.name)
if h.court_status is not None
else None,
)
for h in item.hearings
],
)
@ -267,4 +325,5 @@ def case_blank() -> schemas.CaseBlank:
contactDetail="",
caseConnectedWith="",
bunchCases="",
hearings=[],
)

View File

@ -1,8 +1,9 @@
import uuid
from datetime import date, datetime
from typing import Optional
from typing import List, Optional
from luthor.schemas.hearing import Hearing
from pydantic import BaseModel, Field, validator
from . import to_camel
@ -50,6 +51,8 @@ class CaseIn(BaseModel):
office_status: Optional[OfficeStatusLink]
court_status: Optional[CourtStatusLink]
hearings: List[Hearing]
class Config:
anystr_strip_whitespace = True
alias_generator = to_camel

View File

@ -0,0 +1,47 @@
import uuid
from datetime import date, datetime
from typing import Optional
from luthor.schemas.court_status import CourtStatusLink
from pydantic import BaseModel, Field, validator
from . import to_camel
class HearingIn(BaseModel):
court_number: str
item_number: str
bench: str
proceedings: str
next_hearing_date: Optional[date]
court_status: Optional[CourtStatusLink]
class Config:
anystr_strip_whitespace = True
alias_generator = to_camel
json_encoders = {datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), date: lambda v: v.strftime("%d-%b-%Y")}
@validator("next_hearing_date", pre=True)
def parse_next_hearing_date(cls, value):
if isinstance(value, date):
return value
if value is None:
return None
return datetime.strptime(value, "%d-%b-%Y").date()
class Hearing(HearingIn):
id_: Optional[uuid.UUID]
class Config:
anystr_strip_whitespace = True
alias_generator = to_camel
json_encoders = {datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), date: lambda v: v.strftime("%d-%b-%Y")}
class HearingLink(BaseModel):
id_: uuid.UUID = Field(...)
class Config:
fields = {"id_": "id"}

View File

@ -0,0 +1,16 @@
import { DataSource } from '@angular/cdk/collections';
import { Observable } from 'rxjs';
import { Hearing } from '../../core/hearing';
export class HearingDatasource extends DataSource<Hearing> {
constructor(private data: Observable<Hearing[]>) {
super();
}
connect(): Observable<Hearing[]> {
return this.data;
}
disconnect() {}
}

View File

@ -1,3 +1,6 @@
.example-card {
max-width: 900px;
}
.right-align {
text-align: right;
}

View File

@ -1,10 +1,9 @@
<div fxLayout="row" fxFlex="50%" fxLayoutAlign="space-around center" class="example-card">
<form [formGroup]="form" fxFlex="75%" fxLayout="column">
<mat-card fxFlex>
<mat-card-title-group>
<mat-card-title>Case</mat-card-title>
</mat-card-title-group>
<mat-card-content>
<form [formGroup]="form" fxLayout="column">
<div
fxLayout="row"
fxLayoutAlign="space-around start"
@ -67,6 +66,10 @@
<mat-label>Court Case Number</mat-label>
<input matInput placeholder="Court Case Number" formControlName="courtCaseNumber" />
</mat-form-field>
<mat-form-field fxFlex>
<mat-label>Year</mat-label>
<input matInput placeholder="Year" formControlName="year" />
</mat-form-field>
<mat-form-field fxFlex>
<mat-label>Filing Date</mat-label>
<input
@ -89,26 +92,30 @@
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
>
<mat-form-field fxFlex>
<mat-label>Forum</mat-label>
<mat-select placeholder="Forum" formControlName="court">
<mat-option value=""> -- Not Applicable --</mat-option>
<mat-option *ngFor="let c of courts" [value]="c.id">
{{ c.name }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex>
<mat-label>Case Type</mat-label>
<mat-select placeholder="Case Type" formControlName="caseType">
<mat-option value=""> -- Not Applicable -- </mat-option>
<mat-option value=""> -- Not Applicable --</mat-option>
<mat-option *ngFor="let ct of caseTypes" [value]="ct.id">
{{ ct.name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
>
<mat-form-field fxFlex>
<mat-label>Year</mat-label>
<input matInput placeholder="Year" formControlName="year" />
<mat-label>Appearing for the</mat-label>
<mat-select placeholder="Appearing for the" formControlName="appearOnBehalfOf">
<mat-option value="Petitioner">Petitioner</mat-option>
<mat-option value="Respondent">Respondent</mat-option>
</mat-select>
</mat-form-field>
</div>
<div
@ -123,38 +130,6 @@
<input matInput placeholder="Connected Cases" formControlName="caseConnectedWith" />
</mat-form-field>
</div>
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
>
<mat-form-field fxFlex>
<mat-label>Appearing for the</mat-label>
<mat-select placeholder="Appearing for the" formControlName="appearOnBehalfOf">
<mat-option value="Petitioner">Petitioner</mat-option>
<mat-option value="Respondent">Respondent</mat-option>
</mat-select>
</mat-form-field>
</div>
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
>
<mat-form-field fxFlex>
<mat-label>Forum</mat-label>
<mat-select placeholder="Forum" formControlName="court">
<mat-option value=""> -- Not Applicable -- </mat-option>
<mat-option *ngFor="let c of courts" [value]="c.id">
{{ c.name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div
fxLayout="row"
fxLayoutAlign="space-around start"
@ -165,7 +140,7 @@
<mat-form-field fxFlex>
<mat-label>Department</mat-label>
<mat-select placeholder="Department" formControlName="department">
<mat-option value=""> -- Not Applicable -- </mat-option>
<mat-option value=""> -- Not Applicable --</mat-option>
<mat-option *ngFor="let d of departments" [value]="d.id">
{{ d.name }}
</mat-option>
@ -174,7 +149,7 @@
<mat-form-field fxFlex>
<mat-label>Office</mat-label>
<mat-select placeholder="Office" formControlName="office">
<mat-option value=""> -- Not Applicable -- </mat-option>
<mat-option value=""> -- Not Applicable --</mat-option>
<mat-option *ngFor="let o of offices | async" [value]="o.id">
{{ o.name }}
</mat-option>
@ -190,7 +165,11 @@
>
<mat-form-field fxFlex>
<mat-label>Contact Person</mat-label>
<input matInput placeholder="Contact Person" formControlName="contactDetail" />
<textarea
matInput
placeholder="Contact Person"
formControlName="contactDetail"
></textarea>
</mat-form-field>
</div>
<div
@ -203,7 +182,7 @@
<mat-form-field fxFlex>
<mat-label>Court Status</mat-label>
<mat-select placeholder="Court Status" formControlName="courtStatus">
<mat-option value=""> -- Not Applicable -- </mat-option>
<mat-option value=""> -- Not Applicable --</mat-option>
<mat-option *ngFor="let cs of courtStatuses" [value]="cs.id">
{{ cs.name }}
</mat-option>
@ -212,7 +191,7 @@
<mat-form-field fxFlex>
<mat-label>Office Status</mat-label>
<mat-select placeholder="Office Status" formControlName="officeStatus">
<mat-option value=""> -- Not Applicable -- </mat-option>
<mat-option value=""> -- Not Applicable --</mat-option>
<mat-option *ngFor="let os of officeStatuses" [value]="os.id">
{{ os.name }}
</mat-option>
@ -229,7 +208,7 @@
<mat-form-field fxFlex>
<mat-label>Act</mat-label>
<mat-select placeholder="Act" formControlName="act">
<mat-option value=""> -- Not Applicable -- </mat-option>
<mat-option value=""> -- Not Applicable --</mat-option>
<mat-option *ngFor="let a of acts" [value]="a.id">
{{ a.name }}
</mat-option>
@ -238,7 +217,7 @@
<mat-form-field fxFlex>
<mat-label>Nature</mat-label>
<mat-select placeholder="Nature" formControlName="nature">
<mat-option value=""> -- Not Applicable -- </mat-option>
<mat-option value=""> -- Not Applicable --</mat-option>
<mat-option *ngFor="let n of natures" [value]="n.id">
{{ n.name }}
</mat-option>
@ -282,7 +261,11 @@
>
<mat-form-field fxFlex>
<mat-label>Question of Law</mat-label>
<input matInput placeholder="Question of Law" formControlName="questionOfLaw" />
<textarea
matInput
placeholder="Question of Law"
formControlName="questionOfLaw"
></textarea>
</mat-form-field>
</div>
<div
@ -294,7 +277,7 @@
>
<mat-form-field fxFlex>
<mat-label>Brief Description</mat-label>
<input matInput placeholder="(Synopsis)" formControlName="briefDescription" />
<textarea matInput placeholder="(Synopsis)" formControlName="briefDescription"></textarea>
</mat-form-field>
</div>
<div
@ -343,10 +326,7 @@
#dateOfImpugnedJudgementElement
(focus)="dateOfImpugnedJudgementElement.select()"
/>
<mat-datepicker-toggle
matSuffix
[for]="dateOfImpugnedJudgement"
></mat-datepicker-toggle>
<mat-datepicker-toggle matSuffix [for]="dateOfImpugnedJudgement"></mat-datepicker-toggle>
<mat-datepicker #dateOfImpugnedJudgement></mat-datepicker>
</mat-form-field>
</div>
@ -393,10 +373,164 @@
>
<mat-form-field fxFlex>
<mat-label>Remarks/Status</mat-label>
<input matInput placeholder="Remarks/Status" formControlName="remarks" />
<textarea matInput placeholder="Remarks/Status" formControlName="remarks"></textarea>
</mat-form-field>
</div>
</form>
</mat-card-content>
</mat-card>
<mat-card fxFlex>
<mat-card-title-group>
<mat-card-title>Hearings</mat-card-title>
</mat-card-title-group>
<mat-card-content formGroupName="addRow">
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
>
<mat-form-field fxFlex>
<mat-label>Court Number</mat-label>
<input
type="text"
matInput
placeholder="Court Number"
formControlName="courtNumber"
autocomplete="off"
/>
</mat-form-field>
<mat-form-field fxFlex>
<mat-label>Item Number</mat-label>
<input
type="text"
matInput
placeholder="Item Number"
formControlName="itemNumber"
autocomplete="off"
/>
</mat-form-field>
</div>
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
>
<mat-form-field fxFlex>
<mat-label>Bench</mat-label>
<input
type="text"
matInput
placeholder="Bench"
formControlName="bench"
autocomplete="off"
/>
</mat-form-field>
<mat-form-field fxFlex>
<mat-label>Latest Status</mat-label>
<mat-select placeholder="Latest Status" formControlName="latestStatus">
<mat-option value=""> -- Not Applicable --</mat-option>
<mat-option *ngFor="let cs of courtStatuses" [value]="cs.id">
{{ cs.name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
fx
>
<mat-form-field fxFlex>
<mat-label>Proceedings</mat-label>
<textarea
type="text"
matInput
placeholder="Proceedings"
formControlName="proceedings"
autocomplete="off"
cdkTextareaAutosize
cdkAutosizeMinRows="5"
>
></textarea
>
</mat-form-field>
</div>
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
>
<mat-form-field fxFlex="80%">
<mat-label>Next Hearing Date</mat-label>
<input
matInput
[matDatepicker]="nextHearingDate"
placeholder="Next Hearing Date"
formControlName="nextHearingDate"
autocomplete="off"
#nextHearingDateElement
(focus)="nextHearingDateElement.select()"
/>
<mat-datepicker-toggle matSuffix [for]="nextHearingDate"></mat-datepicker-toggle>
<mat-datepicker #nextHearingDate></mat-datepicker>
</mat-form-field>
<button mat-raised-button color="primary" (click)="addHearing()" fxFlex="80%">Add</button>
</div>
<mat-table #table [dataSource]="dataSource" matSort aria-label="Elements">
<!-- Item Number Column -->
<ng-container matColumnDef="itemNumber">
<mat-header-cell *matHeaderCellDef>Court and Item Number</mat-header-cell>
<mat-cell *matCellDef="let row">{{ row.courtNumber }} / {{ row.itemNumber }}</mat-cell>
</ng-container>
<!-- Bench Column -->
<ng-container matColumnDef="bench">
<mat-header-cell *matHeaderCellDef>Bench</mat-header-cell>
<mat-cell *matCellDef="let row">{{ row.bench }}</mat-cell>
</ng-container>
<!-- Status Column -->
<ng-container matColumnDef="courtStatus">
<mat-header-cell *matHeaderCellDef class="right">Status</mat-header-cell>
<mat-cell *matCellDef="let row" class="right">{{ row.courtStatus?.name }}</mat-cell>
</ng-container>
<!-- Proceedings Column -->
<ng-container matColumnDef="proceedings">
<mat-header-cell *matHeaderCellDef class="right">Proceedings</mat-header-cell>
<mat-cell *matCellDef="let row" class="right">{{ row.proceedings }}</mat-cell>
</ng-container>
<!-- Next Hearing Date Column -->
<ng-container matColumnDef="nextHearingDate">
<mat-header-cell *matHeaderCellDef class="right">Next Hearing</mat-header-cell>
<mat-cell *matCellDef="let row" class="right">{{ row.nextHearingDate }}</mat-cell>
</ng-container>
<!-- Action Column -->
<ng-container matColumnDef="action">
<mat-header-cell *matHeaderCellDef class="center">Action</mat-header-cell>
<mat-cell *matCellDef="let row" class="center">
<button mat-icon-button tabindex="-1" (click)="editRow(row)">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button tabindex="-1" color="warn" (click)="deleteRow(row)">
<mat-icon>delete</mat-icon>
</button>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
</mat-table>
</mat-card-content>
<mat-card-actions>
<button mat-raised-button color="primary" (click)="save()">Save</button>
@ -405,4 +539,4 @@
</button>
</mat-card-actions>
</mat-card>
</div>
</form>

View File

@ -3,7 +3,7 @@ import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import * as moment from 'moment';
import { Observable } from 'rxjs';
import { BehaviorSubject, Observable } from 'rxjs';
import { distinctUntilChanged, startWith, switchMap } from 'rxjs/operators';
import { Act } from '../../core/act';
@ -13,14 +13,17 @@ import { CaseType } from '../../core/case-type';
import { Court } from '../../core/court';
import { CourtStatus } from '../../core/court-status';
import { Department } from '../../core/department';
import { Hearing } from '../../core/hearing';
import { Nature } from '../../core/nature';
import { Office } from '../../core/office';
import { OfficeStatus } from '../../core/office-status';
import { ToasterService } from '../../core/toaster.service';
import { OfficeService } from '../../offices/office.service';
import { ConfirmDialogComponent } from '../../shared/confirm-dialog/confirm-dialog.component';
import { CaseService } from '../case.service';
import { HearingDatasource } from './case-detail-datasource';
import { HearingDialogComponent } from './hearing-dialog.component';
@Component({
selector: 'app-case-detail',
templateUrl: './case-detail.component.html',
@ -28,6 +31,8 @@ import { CaseService } from '../case.service';
})
export class CaseDetailComponent implements OnInit, AfterViewInit {
@ViewChild('nameElement', { static: true }) nameElement?: ElementRef;
public hearingsObservable = new BehaviorSubject<Hearing[]>([]);
dataSource: HearingDatasource = new HearingDatasource(this.hearingsObservable);
form: FormGroup;
caseSources: CaseSource[] = [];
caseTypes: CaseType[] = [];
@ -40,6 +45,15 @@ export class CaseDetailComponent implements OnInit, AfterViewInit {
natures: Nature[] = [];
item: Case = new Case();
displayedColumns = [
'itemNumber',
'bench',
'courtStatus',
'proceedings',
'nextHearingDate',
'action',
];
constructor(
private route: ActivatedRoute,
private router: Router,
@ -80,6 +94,14 @@ export class CaseDetailComponent implements OnInit, AfterViewInit {
nature: '',
officeStatus: '',
courtStatus: '',
addRow: this.fb.group({
courtNumber: '',
itemNumber: '',
bench: '',
latestStatus: '',
proceedings: '',
nextHearingDate: '',
}),
});
}
@ -110,7 +132,7 @@ export class CaseDetailComponent implements OnInit, AfterViewInit {
showItem(item: Case) {
this.item = item;
this.form.setValue({
this.form.patchValue({
caseSource: this.item.caseSource.id,
officeFileNumber: this.item.officeFileNumber,
courtCaseNumber: this.item.courtCaseNumber,
@ -164,6 +186,7 @@ export class CaseDetailComponent implements OnInit, AfterViewInit {
this.form.patchValue({ officeFileNumber: x });
}
});
this.hearingsObservable.next(this.item.hearings);
}
ngAfterViewInit() {
@ -228,7 +251,6 @@ export class CaseDetailComponent implements OnInit, AfterViewInit {
} else {
this.item.limitationDate = moment(formModel.limitationDate).format('DD-MMM-YYYY');
}
console.log(formModel.filingDate);
if (formModel.filingDate === '') {
this.item.filingDate = null;
} else {
@ -320,4 +342,71 @@ export class CaseDetailComponent implements OnInit, AfterViewInit {
}
return this.item;
}
addHearing() {
const formValue = (this.form.get('addRow') as FormControl).value;
const courtNumber: string = formValue.courtNumber;
const itemNumber: string = formValue.itemNumber;
const bench: string = formValue.bench;
const latestStatus =
formValue.latestStatus === ''
? null
: new CourtStatus({
id: formValue.latestStatus,
name: (this.courtStatuses.find((x) => x.id === formValue.latestStatus) as CourtStatus)
.name,
});
const proceedings = formValue.proceedings;
const nextHearingDate =
formValue.nextHearingDate === ''
? null
: moment(formValue.nextHearingDate).format('DD-MMM-YYYY');
this.item.hearings.push(
new Hearing({
courtNumber,
itemNumber,
bench,
courtStatus: latestStatus,
proceedings,
nextHearingDate,
}),
);
this.hearingsObservable.next(this.item.hearings);
this.resetAddRow();
}
resetAddRow() {
(this.form.get('addRow') as FormControl).reset({
courtNumber: '',
itemNumber: '',
bench: '',
courtStatus: '',
proceedings: '',
nextHearingDate: '',
});
}
editRow(row: Hearing) {
const dialogRef = this.dialog.open(HearingDialogComponent, {
width: '750px',
data: { hearing: { ...row }, courtStatuses: this.courtStatuses },
});
dialogRef.afterClosed().subscribe((result: boolean | Hearing) => {
if (!result) {
return;
}
const h = result as Hearing;
Object.assign(row, h);
this.hearingsObservable.next(this.item.hearings);
this.resetAddRow();
});
}
deleteRow(row: Hearing) {
this.item.hearings.splice(this.item.hearings.indexOf(row), 1);
this.hearingsObservable.next(this.item.hearings);
}
}

View File

@ -0,0 +1,109 @@
<h1 mat-dialog-title>Edit Journal Entry</h1>
<div mat-dialog-content>
<form [formGroup]="form">
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
>
<mat-form-field fxFlex>
<mat-label>Court Number</mat-label>
<input
type="text"
matInput
placeholder="Court Number"
formControlName="courtNumber"
autocomplete="off"
/>
</mat-form-field>
<mat-form-field fxFlex>
<mat-label>Item Number</mat-label>
<input
type="text"
matInput
placeholder="Item Number"
formControlName="itemNumber"
autocomplete="off"
/>
</mat-form-field>
</div>
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
>
<mat-form-field fxFlex>
<mat-label>Bench</mat-label>
<input
type="text"
matInput
placeholder="Bench"
formControlName="bench"
autocomplete="off"
/>
</mat-form-field>
<mat-form-field fxFlex>
<mat-label>Latest Status</mat-label>
<mat-select placeholder="Latest Status" formControlName="latestStatus">
<mat-option value=""> -- Not Applicable --</mat-option>
<mat-option *ngFor="let cs of data.courtStatuses" [value]="cs.id">
{{ cs.name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
fx
>
<mat-form-field fxFlex>
<mat-label>Proceedings</mat-label>
<textarea
type="text"
matInput
placeholder="Proceedings"
formControlName="proceedings"
autocomplete="off"
cdkTextareaAutosize
cdkAutosizeMinRows="5"
>
></textarea
>
</mat-form-field>
</div>
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
>
<mat-form-field fxFlex="80%">
<mat-label>Next Hearing Date</mat-label>
<input
matInput
[matDatepicker]="nextHearingDate"
placeholder="Next Hearing Date"
formControlName="nextHearingDate"
autocomplete="off"
#nextHearingDateElement
(focus)="nextHearingDateElement.select()"
/>
<mat-datepicker-toggle matSuffix [for]="nextHearingDate"></mat-datepicker-toggle>
<mat-datepicker #nextHearingDate></mat-datepicker>
</mat-form-field>
</div>
</form>
</div>
<div mat-dialog-actions>
<button mat-button [mat-dialog-close]="false" cdkFocusInitial>Cancel</button>
<button mat-button (click)="accept()" color="primary">Ok</button>
</div>

View File

@ -0,0 +1,26 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { HearingDialogComponent } from './hearing-dialog.component';
describe('HearingDialogComponent', () => {
let component: HearingDialogComponent;
let fixture: ComponentFixture<HearingDialogComponent>;
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [HearingDialogComponent],
}).compileComponents();
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(HearingDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,69 @@
import { Component, Inject, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import * as moment from 'moment';
import { CourtStatus } from '../../core/court-status';
import { Hearing } from '../../core/hearing';
@Component({
selector: 'app-hearing-dialog',
templateUrl: './hearing-dialog.component.html',
styleUrls: ['./hearing-dialog.component.css'],
})
export class HearingDialogComponent implements OnInit {
form: FormGroup;
constructor(
public dialogRef: MatDialogRef<HearingDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: { hearing: Hearing; courtStatuses: CourtStatus[] },
private fb: FormBuilder,
) {
this.form = this.fb.group({
courtNumber: '',
itemNumber: '',
bench: '',
latestStatus: '',
proceedings: '',
nextHearingDate: '',
});
}
ngOnInit() {
this.form.setValue({
courtNumber: this.data.hearing.courtNumber,
itemNumber: this.data.hearing.itemNumber,
bench: this.data.hearing.bench,
latestStatus: this.data.hearing.courtStatus ? this.data.hearing.courtStatus.id : '',
proceedings: this.data.hearing.proceedings,
nextHearingDate: this.data.hearing.nextHearingDate
? moment(this.data.hearing.nextHearingDate, 'DD-MMM-YYYY').toDate()
: '',
});
}
accept(): void {
const formValue = this.form.value;
this.data.hearing.courtNumber = formValue.courtNumber;
this.data.hearing.itemNumber = formValue.itemNumber;
this.data.hearing.bench = formValue.bench;
this.data.hearing.courtStatus =
formValue.latestStatus === ''
? null
: new CourtStatus({
id: formValue.latestStatus,
name: (this.data.courtStatuses.find(
(x) => x.id === formValue.latestStatus,
) as CourtStatus).name,
});
this.data.hearing.proceedings = formValue.proceedings;
if (formValue.nextHearingDate === '') {
this.data.hearing.nextHearingDate = null;
} else {
this.data.hearing.nextHearingDate = moment(formValue.nextHearingDate).format('DD-MMM-YYYY');
}
this.dialogRef.close(this.data.hearing);
}
}

View File

@ -13,6 +13,7 @@ import {
MatNativeDateModule,
} from '@angular/material/core';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatDialogModule } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatPaginatorModule } from '@angular/material/paginator';
@ -21,6 +22,7 @@ import { MatSelectModule } from '@angular/material/select';
import { MatTableModule } from '@angular/material/table';
import { CaseDetailComponent } from './case-detail/case-detail.component';
import { HearingDialogComponent } from './case-detail/hearing-dialog.component';
import { CaseListComponent } from './case-list/case-list.component';
import { CasesRoutingModule } from './cases-routing.module';
@ -52,8 +54,9 @@ export const MY_FORMATS = {
MatSelectModule,
MatPaginatorModule,
MatDatepickerModule,
MatDialogModule,
],
declarations: [CaseListComponent, CaseDetailComponent],
declarations: [CaseListComponent, CaseDetailComponent, HearingDialogComponent],
providers: [
{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
{ provide: MAT_DATE_FORMATS, useValue: MY_FORMATS },

View File

@ -4,6 +4,7 @@ import { CaseType } from './case-type';
import { Court } from './court';
import { CourtStatus } from './court-status';
import { Department } from './department';
import { Hearing } from './hearing';
import { Nature } from './nature';
import { Office } from './office';
import { OfficeStatus } from './office-status';
@ -40,6 +41,7 @@ export class Case {
nature?: Nature;
officeStatus?: OfficeStatus;
courtStatus?: CourtStatus;
hearings: Hearing[];
public constructor(init?: Partial<Case>) {
this.id = undefined;
@ -65,6 +67,7 @@ export class Case {
this.contactDetail = '';
this.caseConnectedWith = '';
this.bunchCases = '';
this.hearings = [];
Object.assign(this, init);
}
}

View File

@ -0,0 +1,22 @@
import { CourtStatus } from './court-status';
export class Hearing {
id: string | undefined;
courtNumber: string;
itemNumber: string;
bench: string;
courtStatus: CourtStatus | null;
proceedings: string;
nextHearingDate: string | null;
public constructor(init?: Partial<Hearing>) {
this.id = undefined;
this.courtNumber = '';
this.itemNumber = '';
this.bench = '';
this.courtStatus = null;
this.proceedings = '';
this.nextHearingDate = '';
Object.assign(this, init);
}
}