Feature: Allow edit of time in guest book.

Feature: Guest book row color is the same as running table colors
This commit is contained in:
Amritanshu Agrawal 2023-03-24 12:46:42 +05:30
parent 94cc8ccd47
commit 2fb2e01ca1
10 changed files with 67 additions and 28 deletions

View File

@ -30,11 +30,11 @@ class GuestBook:
customer: Mapped["Customer"] = relationship("Customer") customer: Mapped["Customer"] = relationship("Customer")
status: Mapped[Optional["Overview"]] = relationship(back_populates="guest", uselist=False) status: Mapped[Optional["Overview"]] = relationship(back_populates="guest", uselist=False)
def __init__(self, pax=None, id_=None, customer_id=None, customer=None): def __init__(self, pax=None, id_=None, customer_id=None, customer=None, date_=None):
self.customer_id = customer_id self.customer_id = customer_id
self.pax = pax self.pax = pax
self.id = id_ self.id = id_
self.date = datetime.utcnow() self.date = datetime.utcnow() if date_ is None else date_
if customer is None: if customer is None:
self.customer_id = customer_id self.customer_id = customer_id
else: else:

View File

@ -38,7 +38,9 @@ def save(
else: else:
customer.name = data.name or customer.name customer.name = data.name or customer.name
customer.address = data.address or customer.address customer.address = data.address or customer.address
item = GuestBook(pax=data.pax, customer=customer) item = GuestBook(
pax=data.pax, customer=customer, date_=data.date_ - timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES)
)
db.add(item) db.add(item)
db.commit() db.commit()
return guest_book_info(item) return guest_book_info(item)
@ -62,6 +64,7 @@ def update_route(
item.customer.phone = data.phone item.customer.phone = data.phone
item.customer.address = data.address item.customer.address = data.address
item.pax = data.pax item.pax = data.pax
item.date = data.date_ - timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES)
db.commit() db.commit()
return guest_book_info(item) return guest_book_info(item)
except SQLAlchemyError as e: except SQLAlchemyError as e:
@ -159,9 +162,15 @@ def guest_book_info(item: GuestBook) -> schemas.GuestBook:
phone=item.customer.phone, phone=item.customer.phone,
pax=item.pax, pax=item.pax,
address=item.customer.address, address=item.customer.address,
date=item.date, date=item.date + timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES),
) )
def blank_guest_book_info() -> schemas.GuestBookIn: def blank_guest_book_info() -> schemas.GuestBookIn:
return schemas.GuestBookIn(name="", phone="", pax=0, address="") return schemas.GuestBookIn(
name="",
phone="",
pax=0,
address="",
date=datetime.utcnow() + timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES),
)

View File

@ -147,7 +147,7 @@ def voucher_info(item: Voucher, db: Session):
"kotId": item.kot_id, "kotId": item.kot_id,
"billId": ", ".join(f"{x.regime.prefix}-{x.bill_number}" for x in item.bills), "billId": ", ".join(f"{x.regime.prefix}-{x.bill_number}" for x in item.bills),
"table": {"id": item.food_table_id, "name": item.food_table.name}, "table": {"id": item.food_table_id, "name": item.food_table.name},
"customer": {"id": item.customer_id, "name": item.customer.name} if item.customer is not None else None, "customer": {"id": item.customer.id, "name": item.customer.name} if item.customer is not None else None,
"narration": item.narration, "narration": item.narration,
"reason": item.reason, "reason": item.reason,
"voucherType": item.voucher_type, "voucherType": item.voucher_type,

View File

@ -12,16 +12,23 @@ class GuestBookIn(BaseModel):
phone: str phone: str
address: str | None address: str | None
pax: int = Field(ge=0) pax: int = Field(ge=0)
date_: datetime
@validator("date_", pre=True)
def parse_date(cls, value):
if isinstance(value, datetime):
return value
return datetime.strptime(value, "%d-%b-%Y %H:%M")
class Config: class Config:
fields = {"id_": "id"} fields = {"id_": "id"}
anystr_strip_whitespace = True anystr_strip_whitespace = True
alias_generator = to_camel alias_generator = to_camel
json_encoders = {datetime: lambda v: v.strftime("%d-%b-%Y %H:%M")}
class GuestBook(GuestBookIn): class GuestBook(GuestBookIn):
id_: uuid.UUID id_: uuid.UUID
date_: datetime
@validator("date_", pre=True) @validator("date_", pre=True)
def parse_date(cls, value): def parse_date(cls, value):

View File

@ -39,6 +39,16 @@
<textarea matInput formControlName="address"></textarea> <textarea matInput formControlName="address"></textarea>
</mat-form-field> </mat-form-field>
</div> </div>
<div class="flex flex-row justify-around content-start items-start">
<mat-form-field class="flex-auto">
<mat-label>Hours</mat-label>
<input matInput formControlName="hours" />
</mat-form-field>
<mat-form-field class="flex-auto">
<mat-label>Minutes</mat-label>
<input matInput formControlName="minutes" />
</mat-form-field>
</div>
</form> </form>
</mat-card-content> </mat-card-content>
<mat-card-actions> <mat-card-actions>

View File

@ -23,6 +23,8 @@ export class GuestBookDetailComponent implements OnInit, AfterViewInit {
phone: FormControl<string | Customer>; phone: FormControl<string | Customer>;
pax: FormControl<number>; pax: FormControl<number>;
address: FormControl<string | null>; address: FormControl<string | null>;
hours: FormControl<number>;
minutes: FormControl<number>;
}>; }>;
item: GuestBook = new GuestBook(); item: GuestBook = new GuestBook();
@ -44,6 +46,8 @@ export class GuestBookDetailComponent implements OnInit, AfterViewInit {
}), }),
pax: new FormControl(0, { validators: Validators.required, nonNullable: true }), pax: new FormControl(0, { validators: Validators.required, nonNullable: true }),
address: new FormControl<string | null>(null), address: new FormControl<string | null>(null),
hours: new FormControl(0, { validators: [Validators.min(0), Validators.max(23)], nonNullable: true }),
minutes: new FormControl(0, { validators: [Validators.min(0), Validators.max(59)], nonNullable: true }),
}); });
// Setup Account Autocomplete // Setup Account Autocomplete
this.customers = this.form.controls.phone.valueChanges.pipe( this.customers = this.form.controls.phone.valueChanges.pipe(
@ -77,6 +81,8 @@ export class GuestBookDetailComponent implements OnInit, AfterViewInit {
phone: item.phone, phone: item.phone,
pax: item.pax, pax: item.pax,
address: item.address, address: item.address,
hours: +item.date.substring(12, 14),
minutes: +item.date.substring(15, 17),
}); });
} }
@ -115,6 +121,9 @@ export class GuestBookDetailComponent implements OnInit, AfterViewInit {
} }
this.item.pax = formModel.pax ?? 0; this.item.pax = formModel.pax ?? 0;
this.item.address = formModel.address ?? null; this.item.address = formModel.address ?? null;
const hours = ('' + (formModel.hours as number)).padStart(2, '0');
const minutes = ('' + (formModel.minutes as number)).padStart(2, '0');
this.item.date = this.item.date.substring(0, 12) + hours + ':' + minutes;
return this.item; return this.item;
} }
} }

View File

@ -1,17 +0,0 @@
.full-width-table {
width: 100%;
}
.running {
background-color: #f53d24;
color: #000000;
}
.printed {
background-color: #00f518;
color: #000000;
}
.center {
display: flex;
justify-content: center;
}

View File

@ -23,7 +23,7 @@
<!-- SNo Column --> <!-- SNo Column -->
<ng-container matColumnDef="sno"> <ng-container matColumnDef="sno">
<mat-header-cell *matHeaderCellDef>S. No</mat-header-cell> <mat-header-cell *matHeaderCellDef>S. No</mat-header-cell>
<mat-cell *matCellDef="let row">{{ row.serial }} {{ row.status }}</mat-cell> <mat-cell *matCellDef="let row">{{ row.serial }}</mat-cell>
</ng-container> </ng-container>
<!-- Name Column --> <!-- Name Column -->
@ -78,8 +78,8 @@
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row <mat-row
*matRowDef="let row; columns: displayedColumns" *matRowDef="let row; columns: displayedColumns"
[class.running]="row.status === 'running'" [class.accent]="row.status === 'running'"
[class.printed]="row.status === 'printed'" [class.strong-accent]="row.status === 'printed'"
></mat-row> ></mat-row>
</mat-table> </mat-table>
</mat-card-content> </mat-card-content>

View File

@ -0,0 +1,21 @@
@use '@angular/material' as mat
$my-primary: mat.define-palette(mat.$indigo-palette, 500)
$my-accent: mat.define-palette(mat.$amber-palette, A200, A100, A400)
table
width: 100%
.center
display: flex
justify-content: center
.accent
/* Read the 200 hue from the primary color palete.*/
color: mat.get-color-from-palette($my-accent, '200-contrast')
background: mat.get-color-from-palette($my-accent, 200)
.strong-accent
/* Read the 700 hue from the primary color palete.*/
color: mat.get-color-from-palette($my-accent, '700-contrast')
background: mat.get-color-from-palette($my-accent, 700)

View File

@ -17,7 +17,7 @@ import { GuestBookListDataSource } from './guest-book-list-datasource';
@Component({ @Component({
selector: 'app-guest-book-list', selector: 'app-guest-book-list',
templateUrl: './guest-book-list.component.html', templateUrl: './guest-book-list.component.html',
styleUrls: ['./guest-book-list.component.css'], styleUrls: ['./guest-book-list.component.sass'],
}) })
export class GuestBookListComponent implements OnInit { export class GuestBookListComponent implements OnInit {
data: BehaviorSubject<GuestBook[]> = new BehaviorSubject<GuestBook[]>([]); data: BehaviorSubject<GuestBook[]> = new BehaviorSubject<GuestBook[]>([]);