236 lines
9.4 KiB
HTML
236 lines
9.4 KiB
HTML
<h2 class="row-container space-between">
|
|
<span>Purchase</span>
|
|
<mat-icon
|
|
matSuffix
|
|
(click)="form.isStarred().value.set(!form.isStarred())"
|
|
class="pointer"
|
|
[class.gold]="form.isStarred()"
|
|
>
|
|
{{ form.isStarred() ? 'star' : 'star_border' }}
|
|
</mat-icon>
|
|
</h2>
|
|
|
|
<form class="flex-col" [formRoot]="form">
|
|
<div class="row-container">
|
|
<mat-form-field class="flex-auto basis-2-5">
|
|
<mat-label>Date</mat-label>
|
|
<input matInput [matDatepicker]="date" [formField]="form.date" autocomplete="off" #dateElement />
|
|
<mat-datepicker-toggle matSuffix [for]="date"></mat-datepicker-toggle>
|
|
<mat-datepicker #date></mat-datepicker>
|
|
</mat-form-field>
|
|
<mat-form-field class="flex-auto basis-2-5">
|
|
<mat-label>Account</mat-label>
|
|
<input
|
|
type="text"
|
|
matInput
|
|
#accountElement
|
|
[matAutocomplete]="autoA"
|
|
[formField]="form.account"
|
|
autocomplete="off"
|
|
/>
|
|
@if (accBal()) {
|
|
<mat-hint>
|
|
Balance as on Date: <strong>{{ accBal()?.date | currency: 'INR' | accounting }}</strong> / Final balance:
|
|
<strong>{{ accBal()?.total | currency: 'INR' | accounting }}</strong>
|
|
</mat-hint>
|
|
}
|
|
<mat-autocomplete #autoA="matAutocomplete" autoActiveFirstOption [displayWith]="displayFn">
|
|
@for (account of accounts(); track account) {
|
|
<mat-option [value]="account">{{ account.name }}</mat-option>
|
|
}
|
|
</mat-autocomplete>
|
|
</mat-form-field>
|
|
<mat-form-field class="flex-auto basis-1-5">
|
|
<mat-label>Amount</mat-label>
|
|
<input type="number" matInput [formField]="form.amount" />
|
|
<span matTextPrefix>₹ </span>
|
|
</mat-form-field>
|
|
</div>
|
|
|
|
<div class="row-container">
|
|
<mat-form-field class="flex-auto basis-1-2">
|
|
<mat-label>Product</mat-label>
|
|
<input
|
|
type="text"
|
|
matInput
|
|
#productElement
|
|
[matAutocomplete]="autoP"
|
|
[formField]="form.addRow.product"
|
|
autocomplete="off"
|
|
/>
|
|
<mat-autocomplete
|
|
#autoP="matAutocomplete"
|
|
autoActiveFirstOption
|
|
[displayWith]="displayFn"
|
|
(optionSelected)="productSelected($event)"
|
|
>
|
|
@for (product of products(); track product) {
|
|
<mat-option [value]="product" [disabled]="!product.id">
|
|
<span [class.gold]="product.isRateContracted">{{ product.name }}</span>
|
|
<!-- <small> ( stock: {{ product.stock }} )</small> -->
|
|
</mat-option>
|
|
}
|
|
</mat-autocomplete>
|
|
</mat-form-field>
|
|
<mat-form-field class="flex-auto basis-10">
|
|
<mat-label>Quantity</mat-label>
|
|
<input type="text" matInput [formField]="form.addRow.quantity" autocomplete="off" />
|
|
</mat-form-field>
|
|
<mat-form-field class="flex-auto basis-10">
|
|
<mat-label>Price</mat-label>
|
|
<input type="text" matInput [formField]="form.addRow.price" autocomplete="off" />
|
|
</mat-form-field>
|
|
<mat-form-field class="flex-auto basis-10">
|
|
<mat-label>Tax</mat-label>
|
|
<input type="text" matInput [formField]="form.addRow.tax" autocomplete="off" />
|
|
</mat-form-field>
|
|
<mat-form-field class="flex-auto basis-10">
|
|
<mat-label>Discount</mat-label>
|
|
<input type="text" matInput [formField]="form.addRow.discount" autocomplete="off" />
|
|
</mat-form-field>
|
|
|
|
<button mat-raised-button color="primary" (click)="addRow()" class="flex-auto basis-10">Add</button>
|
|
</div>
|
|
@if (itemResource.isLoading()) {
|
|
<app-skeleton-loader type="table" [count]="1" />
|
|
} @else if (itemResource.error()) {
|
|
<app-error-state [message]="'Failed to load data.'" (retryAction)="itemResource.reload()" />
|
|
} @else {
|
|
<mat-table #table [dataSource]="form.inventories().value() ?? []" matSort (matSortChange)="sortData($event)">
|
|
<!-- Product Column -->
|
|
<ng-container matColumnDef="product">
|
|
<mat-header-cell *matHeaderCellDef>Product</mat-header-cell>
|
|
<mat-cell *matCellDef="let row">{{ row.batch.sku.name }}</mat-cell>
|
|
</ng-container>
|
|
|
|
<!-- Quantity Column -->
|
|
<ng-container matColumnDef="quantity">
|
|
<mat-header-cell *matHeaderCellDef class="right">Quantity</mat-header-cell>
|
|
<mat-cell *matCellDef="let row" class="right">{{ row.quantity | number: '1.2-2' }}</mat-cell>
|
|
</ng-container>
|
|
|
|
<!-- Rate Column -->
|
|
<ng-container matColumnDef="rate">
|
|
<mat-header-cell *matHeaderCellDef class="right">Rate</mat-header-cell>
|
|
<mat-cell *matCellDef="let row" class="right">{{ row.rate | currency: 'INR' }}</mat-cell>
|
|
</ng-container>
|
|
|
|
<!-- Tax Column -->
|
|
<ng-container matColumnDef="tax">
|
|
<mat-header-cell *matHeaderCellDef class="right">Tax</mat-header-cell>
|
|
<mat-cell *matCellDef="let row" class="right">{{ row.tax | percent: '1.2-2' }}</mat-cell>
|
|
</ng-container>
|
|
|
|
<!-- Discount Column -->
|
|
<ng-container matColumnDef="discount">
|
|
<mat-header-cell *matHeaderCellDef class="right">Discount</mat-header-cell>
|
|
<mat-cell *matCellDef="let row" class="right">{{ row.discount | percent: '1.2-2' }}</mat-cell>
|
|
</ng-container>
|
|
|
|
<!-- Amount Column -->
|
|
<ng-container matColumnDef="amount">
|
|
<mat-header-cell *matHeaderCellDef class="right">Amount</mat-header-cell>
|
|
<mat-cell *matCellDef="let row" class="right">{{ row.amount | currency: 'INR' }}</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>
|
|
<div class="row-container">
|
|
<mat-form-field class="flex-auto">
|
|
<mat-label>Narration</mat-label>
|
|
<textarea matInput matAutosizeMinRows="5" [formField]="form.narration"></textarea>
|
|
</mat-form-field>
|
|
</div>
|
|
<div class="row-container">
|
|
<mat-form-field class="flex-auto">
|
|
<mat-label>Tags</mat-label>
|
|
<mat-chip-grid #chipGrid aria-label="Tag selection">
|
|
@for (tag of form.tagList().value(); track tag) {
|
|
<mat-chip-row (removed)="removeTag(tag)">
|
|
{{ tag.name }}
|
|
<button matChipRemove [attr.aria-label]="'remove ' + tag.name">
|
|
<mat-icon>cancel</mat-icon>
|
|
</button>
|
|
</mat-chip-row>
|
|
}
|
|
</mat-chip-grid>
|
|
<input
|
|
placeholder="New Tag..."
|
|
#tagInput
|
|
[formField]="form.tagInput"
|
|
[matChipInputFor]="chipGrid"
|
|
[matAutocomplete]="autoTag"
|
|
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
|
(matChipInputTokenEnd)="addTag()"
|
|
/>
|
|
<mat-autocomplete #autoTag="matAutocomplete" (optionSelected)="selectedTag($event)">
|
|
@for (tag of tags(); track tag) {
|
|
<mat-option [value]="tag">{{ tag.name }}</mat-option>
|
|
}
|
|
</mat-autocomplete>
|
|
</mat-form-field>
|
|
</div>
|
|
<div class="row-container">
|
|
@for (item of form.files().value(); track item) {
|
|
<div class="img-container" class="flex-auto basis-1-5">
|
|
<img
|
|
[src]="item.thumbnail"
|
|
alt="img"
|
|
(click)="zoomImage(item)"
|
|
(keyup.enter)="zoomImage(item)"
|
|
tabindex="0"
|
|
/>
|
|
<button mat-icon-button class="overlay" (click)="deleteImage(item)">
|
|
<mat-icon>delete</mat-icon>
|
|
</button>
|
|
</div>
|
|
}
|
|
<div class="img-container" class="flex flex-auto basis-1-5">
|
|
<label ng-href for="fileUp">
|
|
<img
|
|
alt="add"
|
|
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTUwIj48cmVjdCB3aWR0aD0iMTAwIiBoZWlnaHQ9IjE1MCIgZmlsbD0iI2VlZSIvPjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjUwIiB5PSI3NSIgc3R5bGU9ImZpbGw6I2FhYTtmb250LXdlaWdodDpib2xkO2ZvbnQtc2l6ZToxMDBweDtmb250LWZhbWlseTpBcmlhbCxIZWx2ZXRpY2Esc2Fucy1zZXJpZjtkb21pbmFudC1iYXNlbGluZTpjZW50cmFsIj4rPC90ZXh0Pjwvc3ZnPg=="
|
|
/>
|
|
</label>
|
|
<input type="file" id="fileUp" multiple accept="image/*" style="display: none" (change)="detectFiles($event)" />
|
|
</div>
|
|
</div>
|
|
}
|
|
</form>
|
|
|
|
<div class="row-container">
|
|
<button mat-raised-button color="primary" (click)="save()" [disabled]="!canSave()" class="">
|
|
{{ id() ? 'Update' : 'Save' }}
|
|
</button>
|
|
@if (id()) {
|
|
<button mat-raised-button (click)="post()" [disabled]="form.posted().controlValue()" class="">
|
|
{{ form.posted().controlValue() ? 'Posted' : 'Post' }}
|
|
</button>
|
|
<button mat-raised-button color="warn" (click)="confirmDelete()" [disabled]="!canSave()">Delete</button>
|
|
}
|
|
<span class="spacer"></span>
|
|
@if (id()) {
|
|
<span class="flex">
|
|
Created on <strong>{{ form.creationDate().value() | localTime }}</strong
|
|
> and Last Edited on <strong>{{ form.lastEditDate().value() | localTime }}</strong
|
|
> by <strong>{{ form.userName().value().name }}</strong
|
|
>.
|
|
{{ form.posted().value() ? 'Posted by ' + form.poster().value() : '' }}
|
|
</span>
|
|
}
|
|
</div>
|