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:
parent
94cc8ccd47
commit
2fb2e01ca1
@ -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:
|
||||||
|
@ -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),
|
||||||
|
)
|
||||||
|
@ -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,
|
||||||
|
@ -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):
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
@ -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>
|
||||||
|
@ -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)
|
@ -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[]>([]);
|
||||||
|
Loading…
Reference in New Issue
Block a user