techlify-inventory-common 18.1.0 → 18.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/inventory-common/inventory-common-routing.module.mjs +11 -1
- package/esm2022/lib/inventory-common/inventory-common.module.mjs +8 -4
- package/esm2022/lib/inventory-common/inventory-dashboard-page/inventory-dashboard-page.component.mjs +10 -8
- package/esm2022/lib/inventory-common/inventory-value-report.service.mjs +21 -0
- package/esm2022/lib/inventory-common/low-stock-report.service.mjs +23 -0
- package/esm2022/lib/inventory-common/product/low-stock-products-widget/low-stock-products-widget.component.mjs +9 -7
- package/esm2022/lib/inventory-common/product/product-list/product-list.component.mjs +3 -3
- package/esm2022/lib/inventory-common/product/product-quick-search/product-quick-search.component.mjs +92 -0
- package/esm2022/lib/inventory-common/product/widgets/product-category-badges/product-category-badges.component.mjs +18 -0
- package/esm2022/lib/inventory-common/reports/inventory-value-report/inventory-value-report.component.mjs +170 -0
- package/esm2022/lib/inventory-common/reports/low-stock-report/low-stock-report.component.mjs +165 -0
- package/esm2022/lib/inventory-common/supplier/supplier-delete-button/supplier-delete-button.component.mjs +64 -0
- package/esm2022/lib/inventory-common/supplier/supplier-form/supplier-form-button/supplier-form-button.component.mjs +43 -0
- package/esm2022/lib/inventory-common/supplier/supplier.module.mjs +11 -3
- package/esm2022/lib/inventory-common/supplier/suppliers-list/suppliers-list.component.mjs +6 -65
- package/fesm2022/{techlify-inventory-common-category.module-CNm2bEsx.mjs → techlify-inventory-common-category.module-BKEBFEeZ.mjs} +9 -9
- package/fesm2022/{techlify-inventory-common-category.module-CNm2bEsx.mjs.map → techlify-inventory-common-category.module-BKEBFEeZ.mjs.map} +1 -1
- package/fesm2022/{techlify-inventory-common-measure.module-BEaRHh5Z.mjs → techlify-inventory-common-measure.module-CZHhYoQd.mjs} +9 -9
- package/fesm2022/{techlify-inventory-common-measure.module-BEaRHh5Z.mjs.map → techlify-inventory-common-measure.module-CZHhYoQd.mjs.map} +1 -1
- package/fesm2022/{techlify-inventory-common-stock-issuances.module-BQRRP-hW.mjs → techlify-inventory-common-stock-issuances.module-BjPbzqUW.mjs} +2 -4
- package/fesm2022/{techlify-inventory-common-stock-issuances.module-BQRRP-hW.mjs.map → techlify-inventory-common-stock-issuances.module-BjPbzqUW.mjs.map} +1 -1
- package/fesm2022/{techlify-inventory-common-supplier.module-Bwa7gx14.mjs → techlify-inventory-common-supplier.module-CFDwJ-TS.mjs} +251 -218
- package/fesm2022/techlify-inventory-common-supplier.module-CFDwJ-TS.mjs.map +1 -0
- package/fesm2022/techlify-inventory-common-techlify-inventory-common-CYiCJfk9.mjs +3143 -0
- package/fesm2022/techlify-inventory-common-techlify-inventory-common-CYiCJfk9.mjs.map +1 -0
- package/fesm2022/techlify-inventory-common.mjs +1 -1
- package/lib/inventory-common/inventory-common.module.d.ts +2 -1
- package/lib/inventory-common/inventory-value-report.service.d.ts +9 -0
- package/lib/inventory-common/low-stock-report.service.d.ts +10 -0
- package/lib/inventory-common/product/product-quick-search/product-quick-search.component.d.ts +15 -0
- package/lib/inventory-common/product/widgets/product-category-badges/product-category-badges.component.d.ts +6 -0
- package/lib/inventory-common/reports/inventory-value-report/inventory-value-report.component.d.ts +26 -0
- package/lib/inventory-common/reports/low-stock-report/low-stock-report.component.d.ts +26 -0
- package/lib/inventory-common/supplier/supplier-delete-button/supplier-delete-button.component.d.ts +18 -0
- package/lib/inventory-common/supplier/supplier-form/supplier-form-button/supplier-form-button.component.d.ts +13 -0
- package/lib/inventory-common/supplier/supplier.module.d.ts +3 -1
- package/lib/inventory-common/supplier/suppliers-list/suppliers-list.component.d.ts +0 -8
- package/package.json +1 -1
- package/fesm2022/techlify-inventory-common-product.module-BV9Cy88x.mjs +0 -1168
- package/fesm2022/techlify-inventory-common-product.module-BV9Cy88x.mjs.map +0 -1
- package/fesm2022/techlify-inventory-common-stock-issuances-list.module-Dt6gx-ji.mjs +0 -436
- package/fesm2022/techlify-inventory-common-stock-issuances-list.module-Dt6gx-ji.mjs.map +0 -1
- package/fesm2022/techlify-inventory-common-stock-receipt-form.module-DND0GNlf.mjs +0 -302
- package/fesm2022/techlify-inventory-common-stock-receipt-form.module-DND0GNlf.mjs.map +0 -1
- package/fesm2022/techlify-inventory-common-stock-receipts.module-BvYaKITT.mjs +0 -253
- package/fesm2022/techlify-inventory-common-stock-receipts.module-BvYaKITT.mjs.map +0 -1
- package/fesm2022/techlify-inventory-common-supplier-form.component-DVBnhiyH.mjs +0 -177
- package/fesm2022/techlify-inventory-common-supplier-form.component-DVBnhiyH.mjs.map +0 -1
- package/fesm2022/techlify-inventory-common-supplier.module-Bwa7gx14.mjs.map +0 -1
- package/fesm2022/techlify-inventory-common-techlify-form-service-CiVfwYTS.mjs +0 -14
- package/fesm2022/techlify-inventory-common-techlify-form-service-CiVfwYTS.mjs.map +0 -1
- package/fesm2022/techlify-inventory-common-techlify-inventory-common-GFYF7JCA.mjs +0 -495
- package/fesm2022/techlify-inventory-common-techlify-inventory-common-GFYF7JCA.mjs.map +0 -1
|
@@ -1,1168 +0,0 @@
|
|
|
1
|
-
import * as i0 from '@angular/core';
|
|
2
|
-
import { Inject, Component, Injectable, EventEmitter, Input, Output, NgModule } from '@angular/core';
|
|
3
|
-
import * as i4 from '@angular/common';
|
|
4
|
-
import { CommonModule } from '@angular/common';
|
|
5
|
-
import { __decorate } from 'tslib';
|
|
6
|
-
import * as i2 from '@angular/forms';
|
|
7
|
-
import { Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
|
|
8
|
-
import * as i1 from '@angular/material/dialog';
|
|
9
|
-
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
|
|
10
|
-
import { P as ProductService, S as StockSummaryService } from './techlify-inventory-common-techlify-inventory-common-GFYF7JCA.mjs';
|
|
11
|
-
import * as i3 from 'ngx-spinner';
|
|
12
|
-
import * as i1$1 from 'ngx-techlify-core';
|
|
13
|
-
import { TechlifyServiceBaseClass, TechlifyFormComponentInterface, TechlifyListingControllerInterface, AuthenticationGuard, MaterialModule, SearchableSelectorModule, TimelineFilterModule, ImportCsvModule, ColumnSelectorModule } from 'ngx-techlify-core';
|
|
14
|
-
import * as i7 from '@angular/material/button';
|
|
15
|
-
import * as i6 from '@angular/material/form-field';
|
|
16
|
-
import * as i7$1 from '@angular/material/input';
|
|
17
|
-
import * as i10 from '@angular/flex-layout';
|
|
18
|
-
import { FlexModule } from '@angular/flex-layout';
|
|
19
|
-
import * as i6$1 from '@angular/material/table';
|
|
20
|
-
import { MatTableDataSource } from '@angular/material/table';
|
|
21
|
-
import { debounceTime } from 'rxjs/operators';
|
|
22
|
-
import { untilDestroyed, UntilDestroy } from '@ngneat/until-destroy';
|
|
23
|
-
import * as i2$1 from '@angular/router';
|
|
24
|
-
import { RouterModule } from '@angular/router';
|
|
25
|
-
import * as i3$1 from '@angular/material/icon';
|
|
26
|
-
import * as i10$1 from '@angular/material/core';
|
|
27
|
-
import * as i11 from '@angular/material/select';
|
|
28
|
-
import * as i5 from '@angular/material/sort';
|
|
29
|
-
import * as i10$2 from 'ngx-infinite-scroll';
|
|
30
|
-
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
|
|
31
|
-
import moment from 'moment';
|
|
32
|
-
import { T as TechlifyFormService } from './techlify-inventory-common-techlify-form-service-CiVfwYTS.mjs';
|
|
33
|
-
import * as i9 from '@angular/material/datepicker';
|
|
34
|
-
import { a as StockReceiptFormButtonComponent, S as StockReceiptFormModule } from './techlify-inventory-common-stock-receipt-form.module-DND0GNlf.mjs';
|
|
35
|
-
import { c as StockIssueFormButtonComponent, S as StockIssuancesListComponent, a as StockIssueFormModule, b as StockIssuancesListModule } from './techlify-inventory-common-stock-issuances-list.module-Dt6gx-ji.mjs';
|
|
36
|
-
import * as i3$2 from '@angular/material/card';
|
|
37
|
-
import * as i2$2 from '@angular/material/tooltip';
|
|
38
|
-
import * as i7$2 from '@angular/material/progress-bar';
|
|
39
|
-
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
40
|
-
import { S as StockReceiptsListPageComponent, a as StockReceiptsModule } from './techlify-inventory-common-stock-receipts.module-BvYaKITT.mjs';
|
|
41
|
-
import * as i6$2 from '@angular/material/divider';
|
|
42
|
-
|
|
43
|
-
const errorMessages$1 = {
|
|
44
|
-
title: {
|
|
45
|
-
required: "Please Enter Title",
|
|
46
|
-
},
|
|
47
|
-
description: {
|
|
48
|
-
required: "Please Enter Description",
|
|
49
|
-
},
|
|
50
|
-
};
|
|
51
|
-
class ProductMeasureFormComponent {
|
|
52
|
-
productService;
|
|
53
|
-
fb;
|
|
54
|
-
dialogRef;
|
|
55
|
-
data;
|
|
56
|
-
spinnerService;
|
|
57
|
-
formValidatorService;
|
|
58
|
-
errorService;
|
|
59
|
-
alertService;
|
|
60
|
-
productMeasureForm;
|
|
61
|
-
isWorking = false;
|
|
62
|
-
isUpdate = false;
|
|
63
|
-
constructor(productService, fb, dialogRef, data, spinnerService, formValidatorService, errorService, alertService) {
|
|
64
|
-
this.productService = productService;
|
|
65
|
-
this.fb = fb;
|
|
66
|
-
this.dialogRef = dialogRef;
|
|
67
|
-
this.data = data;
|
|
68
|
-
this.spinnerService = spinnerService;
|
|
69
|
-
this.formValidatorService = formValidatorService;
|
|
70
|
-
this.errorService = errorService;
|
|
71
|
-
this.alertService = alertService;
|
|
72
|
-
this.productMeasureForm = this.fb.group({
|
|
73
|
-
id: [""],
|
|
74
|
-
title: ["", Validators.compose([Validators.required])],
|
|
75
|
-
description: ["", Validators.compose([Validators.required])],
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
ngOnInit() {
|
|
79
|
-
if (this.data.details) {
|
|
80
|
-
this.isUpdate = true;
|
|
81
|
-
this.productMeasureForm.patchValue(this.data.details);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
async save() {
|
|
85
|
-
if (!this.productMeasureForm.valid) {
|
|
86
|
-
this.alertService.addAlert("Please Fill All Required Fields", "warn");
|
|
87
|
-
this.productMeasureForm.markAllAsTouched();
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
let productMeasure = this.productMeasureForm.value;
|
|
91
|
-
try {
|
|
92
|
-
this.spinnerService.show();
|
|
93
|
-
this.isWorking = true;
|
|
94
|
-
let result = this.isUpdate
|
|
95
|
-
? await this.productService.updateProductMeasure(productMeasure)
|
|
96
|
-
: await this.productService.createProductMeasure(productMeasure);
|
|
97
|
-
this.dialogRef.close(result);
|
|
98
|
-
}
|
|
99
|
-
catch (error) {
|
|
100
|
-
this.errorService.handleError(error);
|
|
101
|
-
}
|
|
102
|
-
finally {
|
|
103
|
-
this.isWorking = false;
|
|
104
|
-
this.spinnerService.hide();
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Method to evaluate form fields
|
|
109
|
-
*/
|
|
110
|
-
isFieldValid(field) {
|
|
111
|
-
return this.formValidatorService.isFieldValid(field, this.productMeasureForm);
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Method to find error in form fields
|
|
115
|
-
*/
|
|
116
|
-
getErrorMessage(field) {
|
|
117
|
-
return this.formValidatorService.getErrorMessage(field, this.productMeasureForm, errorMessages$1);
|
|
118
|
-
}
|
|
119
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductMeasureFormComponent, deps: [{ token: ProductService }, { token: i2.FormBuilder }, { token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: i3.NgxSpinnerService }, { token: i1$1.FormValidatorService }, { token: i1$1.ErrorHandlerService }, { token: i1$1.AlertService }], target: i0.ɵɵFactoryTarget.Component });
|
|
120
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ProductMeasureFormComponent, selector: "app-product-measure-form", ngImport: i0, template: "<div>\n <form [formGroup]=\"productMeasureForm\" (ngSubmit)=\"save()\">\n <h3 class=\"text-center\">Create/Update Product Measure</h3>\n <div fxLayout=\"column\">\n <div fxLayout=\"column\">\n <mat-form-field>\n <input\n matInput\n placeholder=\"Title\"\n formControlName=\"title\"\n required\n />\n <mat-error *ngIf=\"isFieldValid('title')\"\n >{{ getErrorMessage(\"title\") }}\n </mat-error>\n </mat-form-field>\n <mat-form-field>\n <input\n matInput\n placeholder=\"Description\"\n formControlName=\"description\"\n required\n />\n <mat-error *ngIf=\"isFieldValid('description')\"\n >{{ getErrorMessage(\"description\") }}\n </mat-error>\n </mat-form-field>\n <div fxFlex=\"100%\" fxLayout fxLayoutGap=\"1rem\">\n <button\n mat-button\n class=\"mt-2\"\n type=\"button\"\n (click)=\"dialogRef.close()\"\n >\n Cancel\n </button>\n <button mat-raised-button color=\"primary\" class=\"mt-2\" type=\"submit\">\n Save\n </button>\n </div>\n </div>\n </div>\n </form>\n</div>\n", dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i7.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i7$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i10.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i10.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i10.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], preserveWhitespaces: true });
|
|
121
|
-
}
|
|
122
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductMeasureFormComponent, decorators: [{
|
|
123
|
-
type: Component,
|
|
124
|
-
args: [{ selector: "app-product-measure-form", template: "<div>\n <form [formGroup]=\"productMeasureForm\" (ngSubmit)=\"save()\">\n <h3 class=\"text-center\">Create/Update Product Measure</h3>\n <div fxLayout=\"column\">\n <div fxLayout=\"column\">\n <mat-form-field>\n <input\n matInput\n placeholder=\"Title\"\n formControlName=\"title\"\n required\n />\n <mat-error *ngIf=\"isFieldValid('title')\"\n >{{ getErrorMessage(\"title\") }}\n </mat-error>\n </mat-form-field>\n <mat-form-field>\n <input\n matInput\n placeholder=\"Description\"\n formControlName=\"description\"\n required\n />\n <mat-error *ngIf=\"isFieldValid('description')\"\n >{{ getErrorMessage(\"description\") }}\n </mat-error>\n </mat-form-field>\n <div fxFlex=\"100%\" fxLayout fxLayoutGap=\"1rem\">\n <button\n mat-button\n class=\"mt-2\"\n type=\"button\"\n (click)=\"dialogRef.close()\"\n >\n Cancel\n </button>\n <button mat-raised-button color=\"primary\" class=\"mt-2\" type=\"submit\">\n Save\n </button>\n </div>\n </div>\n </div>\n </form>\n</div>\n" }]
|
|
125
|
-
}], ctorParameters: () => [{ type: ProductService }, { type: i2.FormBuilder }, { type: i1.MatDialogRef }, { type: undefined, decorators: [{
|
|
126
|
-
type: Inject,
|
|
127
|
-
args: [MAT_DIALOG_DATA]
|
|
128
|
-
}] }, { type: i3.NgxSpinnerService }, { type: i1$1.FormValidatorService }, { type: i1$1.ErrorHandlerService }, { type: i1$1.AlertService }] });
|
|
129
|
-
|
|
130
|
-
let ProductMeasuresListComponent = class ProductMeasuresListComponent {
|
|
131
|
-
fb;
|
|
132
|
-
dialog;
|
|
133
|
-
filterService;
|
|
134
|
-
activatedRoute;
|
|
135
|
-
productService;
|
|
136
|
-
filterFormGroup;
|
|
137
|
-
lastPage;
|
|
138
|
-
page = 1;
|
|
139
|
-
perPage = 25;
|
|
140
|
-
totalItems = 0;
|
|
141
|
-
currentPage = 1;
|
|
142
|
-
num_items = 25;
|
|
143
|
-
routeFilters;
|
|
144
|
-
productMeasures = [];
|
|
145
|
-
columnDefinitions = [
|
|
146
|
-
{ def: "#", isShow: true },
|
|
147
|
-
{ def: "Title", isShow: true },
|
|
148
|
-
{ def: "Description", isShow: true },
|
|
149
|
-
{ def: "Actions", isShow: true },
|
|
150
|
-
];
|
|
151
|
-
displayedColumns = ["#", "Title", "Description", "Actions"];
|
|
152
|
-
dataSource = new MatTableDataSource();
|
|
153
|
-
constructor(fb, dialog, filterService, activatedRoute, productService) {
|
|
154
|
-
this.fb = fb;
|
|
155
|
-
this.dialog = dialog;
|
|
156
|
-
this.filterService = filterService;
|
|
157
|
-
this.activatedRoute = activatedRoute;
|
|
158
|
-
this.productService = productService;
|
|
159
|
-
this.filterFormGroup = this.fb.group({
|
|
160
|
-
num_items: [this.num_items + "|" + this.currentPage],
|
|
161
|
-
search: [""],
|
|
162
|
-
type_ids: [""],
|
|
163
|
-
sort_by: [""],
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
ngOnInit() {
|
|
167
|
-
this.patchFiltersFromRoute();
|
|
168
|
-
this.listenForChanges();
|
|
169
|
-
this.loadData();
|
|
170
|
-
}
|
|
171
|
-
listenForChanges() {
|
|
172
|
-
this.filterFormGroup.valueChanges
|
|
173
|
-
.pipe(debounceTime(500), untilDestroyed(this))
|
|
174
|
-
.subscribe((changes) => {
|
|
175
|
-
this.filterService.applyFilterToRoute(this.activatedRoute, this.filterFormGroup.value);
|
|
176
|
-
this.reload();
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
patchFiltersFromRoute() {
|
|
180
|
-
this.routeFilters = this.filterService.getFiltersFromRoute(this.activatedRoute, this.filterFormGroup.value);
|
|
181
|
-
this.filterFormGroup.setValue(this.routeFilters);
|
|
182
|
-
if (this.routeFilters.type_ids) {
|
|
183
|
-
this.filterFormGroup
|
|
184
|
-
.get("type_ids")
|
|
185
|
-
.setValue(this.routeFilters.type_ids.split(",").map(Number));
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
async loadData() {
|
|
189
|
-
let filters = this.filterFormGroup.value;
|
|
190
|
-
filters.page = this.page;
|
|
191
|
-
filters.per_page = this.perPage;
|
|
192
|
-
filters.type_ids = filters.type_ids.toString();
|
|
193
|
-
filters.num_items = this.num_items + "|" + this.currentPage;
|
|
194
|
-
let res = await this.productService.getProductMeasures(filters);
|
|
195
|
-
if (this.productMeasures.length < 1) {
|
|
196
|
-
this.productMeasures = res.data;
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
199
|
-
res.data.forEach((item) => this.productMeasures.push(item));
|
|
200
|
-
}
|
|
201
|
-
this.dataSource = new MatTableDataSource(this.productMeasures);
|
|
202
|
-
this.totalItems = res.total;
|
|
203
|
-
this.lastPage = res.last_page || this.page;
|
|
204
|
-
}
|
|
205
|
-
reload() {
|
|
206
|
-
this.productMeasures = [];
|
|
207
|
-
this.currentPage = 1;
|
|
208
|
-
this.loadData();
|
|
209
|
-
}
|
|
210
|
-
modifyProductMeasure(model) {
|
|
211
|
-
const dialogRef = this.dialog.open(ProductMeasureFormComponent, {
|
|
212
|
-
width: "600px",
|
|
213
|
-
data: {
|
|
214
|
-
details: model,
|
|
215
|
-
},
|
|
216
|
-
});
|
|
217
|
-
dialogRef.afterClosed().subscribe((result) => {
|
|
218
|
-
if (result) {
|
|
219
|
-
this.reload();
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
onScroll() {
|
|
224
|
-
if (this.totalItems > this.productMeasures.length) {
|
|
225
|
-
this.currentPage += 1;
|
|
226
|
-
this.loadData();
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
assignFilter(column, direction) {
|
|
230
|
-
if (column) {
|
|
231
|
-
return this.filterFormGroup
|
|
232
|
-
.get("sort_by")
|
|
233
|
-
?.setValue(column + "|" + direction);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
sortColumn(event) {
|
|
237
|
-
var direction = event.direction.toString().toUpperCase();
|
|
238
|
-
this.assignFilter(event.active, direction);
|
|
239
|
-
}
|
|
240
|
-
// eslint-disable-next-line @angular-eslint/use-lifecycle-interface
|
|
241
|
-
// eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method
|
|
242
|
-
ngOnDestroy() {
|
|
243
|
-
//Called once, before the instance is destroyed.
|
|
244
|
-
//Add 'implements OnDestroy' to the class.
|
|
245
|
-
}
|
|
246
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductMeasuresListComponent, deps: [{ token: i2.FormBuilder }, { token: i1.MatDialog }, { token: i1$1.FilterService }, { token: i2$1.ActivatedRoute }, { token: ProductService }], target: i0.ɵɵFactoryTarget.Component });
|
|
247
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ProductMeasuresListComponent, selector: "app-product-measure-list", ngImport: i0, template: "<div fxLayout=\"column\">\n <div class=\"text-center\" fxLayoutAlign=\"center center\">\n <h3 fxLayout>\n <span class=\"mt-1\"> Product Measures </span>\n <button\n mat-raised-button\n class=\"ml-2\"\n color=\"primary\"\n (click)=\"modifyProductMeasure()\"\n >\n <mat-icon>add</mat-icon>\n Product Measure\n </button>\n </h3>\n </div>\n\n <div fxLayout>\n <form [formGroup]=\"filterFormGroup\" fxLayout fxLayoutGap=\"0.5rem\">\n <mat-form-field>\n <input\n matInput\n placeholder=\"Item Name, Description, etc.\"\n formControlName=\"search\"\n />\n </mat-form-field>\n </form>\n\n <mat-form-field class=\"ml-2\" fxFlex=\"0 1 calc(11.11% - 0.5rem)\">\n <mat-label>Columns</mat-label>\n <mat-select [(ngModel)]=\"displayedColumns\" multiple name=\"column\">\n <mat-option\n *ngFor=\"let column of columnDefinitions\"\n [value]=\"column.def\"\n [disabled]=\"!column.isShow\"\n >\n {{ column?.def }}</mat-option\n >\n </mat-select>\n </mat-form-field>\n </div>\n\n <table\n mat-table\n #table\n [dataSource]=\"dataSource\"\n class=\"mat-elevation-z8 w-100 mt-4 table-hover\"\n infiniteScroll\n [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\"\n (scrolled)=\"onScroll()\"\n [fromRoot]=\"true\"\n infiniteScrollContainer=\"mat-sidenav-content\"\n matSort\n (matSortChange)=\"sortColumn($event)\"\n matSortDisableClear=\"true\"\n >\n <!-- # Column -->\n <ng-container matColumnDef=\"#\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <!-- Title Column -->\n <ng-container matColumnDef=\"Title\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Title</th>\n <td mat-cell *matCellDef=\"let element\">{{ element.title }}</td>\n </ng-container>\n\n <!-- Description Column -->\n <ng-container matColumnDef=\"Description\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Description</th>\n <td mat-cell *matCellDef=\"let element\">{{ element.description }}</td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"Actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"text-secondary\" fxLayoutGap=\"1rem\">\n <button mat-icon-button (click)=\"modifyProductMeasure(element)\">\n <mat-icon>edit</mat-icon>\n </button>\n </div>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n</div>\n", dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: i7.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i7.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i10$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i11.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i5.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i5.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i6$1.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6$1.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6$1.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6$1.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i6$1.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6$1.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6$1.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6$1.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6$1.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6$1.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i10$2.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "directive", type: i10.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i10.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i10.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i10.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], preserveWhitespaces: true });
|
|
248
|
-
};
|
|
249
|
-
ProductMeasuresListComponent = __decorate([
|
|
250
|
-
UntilDestroy()
|
|
251
|
-
], ProductMeasuresListComponent);
|
|
252
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductMeasuresListComponent, decorators: [{
|
|
253
|
-
type: Component,
|
|
254
|
-
args: [{ selector: "app-product-measure-list", template: "<div fxLayout=\"column\">\n <div class=\"text-center\" fxLayoutAlign=\"center center\">\n <h3 fxLayout>\n <span class=\"mt-1\"> Product Measures </span>\n <button\n mat-raised-button\n class=\"ml-2\"\n color=\"primary\"\n (click)=\"modifyProductMeasure()\"\n >\n <mat-icon>add</mat-icon>\n Product Measure\n </button>\n </h3>\n </div>\n\n <div fxLayout>\n <form [formGroup]=\"filterFormGroup\" fxLayout fxLayoutGap=\"0.5rem\">\n <mat-form-field>\n <input\n matInput\n placeholder=\"Item Name, Description, etc.\"\n formControlName=\"search\"\n />\n </mat-form-field>\n </form>\n\n <mat-form-field class=\"ml-2\" fxFlex=\"0 1 calc(11.11% - 0.5rem)\">\n <mat-label>Columns</mat-label>\n <mat-select [(ngModel)]=\"displayedColumns\" multiple name=\"column\">\n <mat-option\n *ngFor=\"let column of columnDefinitions\"\n [value]=\"column.def\"\n [disabled]=\"!column.isShow\"\n >\n {{ column?.def }}</mat-option\n >\n </mat-select>\n </mat-form-field>\n </div>\n\n <table\n mat-table\n #table\n [dataSource]=\"dataSource\"\n class=\"mat-elevation-z8 w-100 mt-4 table-hover\"\n infiniteScroll\n [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\"\n (scrolled)=\"onScroll()\"\n [fromRoot]=\"true\"\n infiniteScrollContainer=\"mat-sidenav-content\"\n matSort\n (matSortChange)=\"sortColumn($event)\"\n matSortDisableClear=\"true\"\n >\n <!-- # Column -->\n <ng-container matColumnDef=\"#\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <!-- Title Column -->\n <ng-container matColumnDef=\"Title\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Title</th>\n <td mat-cell *matCellDef=\"let element\">{{ element.title }}</td>\n </ng-container>\n\n <!-- Description Column -->\n <ng-container matColumnDef=\"Description\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Description</th>\n <td mat-cell *matCellDef=\"let element\">{{ element.description }}</td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"Actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"text-secondary\" fxLayoutGap=\"1rem\">\n <button mat-icon-button (click)=\"modifyProductMeasure(element)\">\n <mat-icon>edit</mat-icon>\n </button>\n </div>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n</div>\n" }]
|
|
255
|
-
}], ctorParameters: () => [{ type: i2.FormBuilder }, { type: i1.MatDialog }, { type: i1$1.FilterService }, { type: i2$1.ActivatedRoute }, { type: ProductService }] });
|
|
256
|
-
|
|
257
|
-
class ProductFormService extends TechlifyFormService {
|
|
258
|
-
constructor() {
|
|
259
|
-
super();
|
|
260
|
-
}
|
|
261
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductFormService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
262
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductFormService, providedIn: "root" });
|
|
263
|
-
}
|
|
264
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductFormService, decorators: [{
|
|
265
|
-
type: Injectable,
|
|
266
|
-
args: [{
|
|
267
|
-
providedIn: "root",
|
|
268
|
-
}]
|
|
269
|
-
}], ctorParameters: () => [] });
|
|
270
|
-
|
|
271
|
-
const initial_quantity = 0;
|
|
272
|
-
const reorder_point = 10;
|
|
273
|
-
const errorMessages = {
|
|
274
|
-
type_id: {
|
|
275
|
-
required: "Please Enter Type",
|
|
276
|
-
},
|
|
277
|
-
name: {
|
|
278
|
-
required: "Please Enter Name",
|
|
279
|
-
},
|
|
280
|
-
sale_price: {
|
|
281
|
-
required: "Please Enter Sales Price",
|
|
282
|
-
},
|
|
283
|
-
minimum_price: {
|
|
284
|
-
required: "Please Enter Minimum Price",
|
|
285
|
-
},
|
|
286
|
-
reorder_point: {
|
|
287
|
-
required: "Please Enter Reorder Point",
|
|
288
|
-
},
|
|
289
|
-
};
|
|
290
|
-
class ProductFormComponent {
|
|
291
|
-
productService;
|
|
292
|
-
fb;
|
|
293
|
-
formValidatorService;
|
|
294
|
-
alertService;
|
|
295
|
-
datePipe;
|
|
296
|
-
productFormService;
|
|
297
|
-
productForm;
|
|
298
|
-
isWorking = false;
|
|
299
|
-
isUpdate = false;
|
|
300
|
-
saved = new EventEmitter();
|
|
301
|
-
cancelled = new EventEmitter();
|
|
302
|
-
product;
|
|
303
|
-
displayedFormFields = [
|
|
304
|
-
"name",
|
|
305
|
-
"product type",
|
|
306
|
-
"sku",
|
|
307
|
-
"description",
|
|
308
|
-
"product measure",
|
|
309
|
-
"reorder point",
|
|
310
|
-
"initial quantity",
|
|
311
|
-
"initial quantity date",
|
|
312
|
-
"sales price",
|
|
313
|
-
"minimum price",
|
|
314
|
-
"maximum price",
|
|
315
|
-
"income account",
|
|
316
|
-
"expense account",
|
|
317
|
-
];
|
|
318
|
-
displayedFormSections = [
|
|
319
|
-
"basic information",
|
|
320
|
-
"inventory information",
|
|
321
|
-
"sales information",
|
|
322
|
-
"accounts information",
|
|
323
|
-
];
|
|
324
|
-
constructor(productService, fb, formValidatorService, alertService, datePipe, productFormService) {
|
|
325
|
-
this.productService = productService;
|
|
326
|
-
this.fb = fb;
|
|
327
|
-
this.formValidatorService = formValidatorService;
|
|
328
|
-
this.alertService = alertService;
|
|
329
|
-
this.datePipe = datePipe;
|
|
330
|
-
this.productFormService = productFormService;
|
|
331
|
-
this.productForm = this.fb.group({
|
|
332
|
-
id: [""],
|
|
333
|
-
type_id: [1, Validators.compose([Validators.required])],
|
|
334
|
-
sku: [""],
|
|
335
|
-
name: ["", Validators.compose([Validators.required])],
|
|
336
|
-
initial_quantity: [initial_quantity],
|
|
337
|
-
initial_quantity_date: [moment().format()],
|
|
338
|
-
reorder_point: [reorder_point, Validators.compose([Validators.required])],
|
|
339
|
-
description: [""],
|
|
340
|
-
sale_price: [0, Validators.compose([Validators.required])],
|
|
341
|
-
income_account_id: [""],
|
|
342
|
-
expense_account_id: [""],
|
|
343
|
-
measure_id: [1],
|
|
344
|
-
minimum_price: ["", Validators.compose([Validators.required])],
|
|
345
|
-
maximum_price: [""],
|
|
346
|
-
condition_type_id: [1],
|
|
347
|
-
current_quantity: [],
|
|
348
|
-
category_ids: [""],
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
ngOnInit() {
|
|
352
|
-
if (this.product?.id) {
|
|
353
|
-
this.isUpdate = true;
|
|
354
|
-
let data = { ...this.product };
|
|
355
|
-
if (this.product?.categories?.length > 0) {
|
|
356
|
-
data.category_ids = this.product.categories.map((category) => category?.id);
|
|
357
|
-
}
|
|
358
|
-
if (data?.initial_quantity_date) {
|
|
359
|
-
data.initial_quantity_date = moment(data.initial_quantity_date).toISOString();
|
|
360
|
-
}
|
|
361
|
-
this.productForm.patchValue(data);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
async save() {
|
|
365
|
-
this.productForm.markAllAsTouched();
|
|
366
|
-
if (this.productForm.invalid) {
|
|
367
|
-
this.alertService.addAlert("Please Fill All Required Fields", "warn");
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
let product = this.productForm.value;
|
|
371
|
-
if (product.maximum_price <= 0 || !product.maximum_price) {
|
|
372
|
-
product.maximum_price = product.minimum_price;
|
|
373
|
-
}
|
|
374
|
-
if (product?.initial_quantity_date) {
|
|
375
|
-
product.initial_quantity_date = moment(product.initial_quantity_date).format("YYYY-MM-DD");
|
|
376
|
-
}
|
|
377
|
-
this.isWorking = true;
|
|
378
|
-
product.with = "type,measure,incomeAccount,expenseAccount";
|
|
379
|
-
let request = this.productService.store(product);
|
|
380
|
-
if (this.isUpdate) {
|
|
381
|
-
request = this.productService.update(product);
|
|
382
|
-
}
|
|
383
|
-
request.subscribe({
|
|
384
|
-
next: (response) => {
|
|
385
|
-
this.saved.emit(response?.item);
|
|
386
|
-
this.isWorking = false;
|
|
387
|
-
this.productFormService.listUpdated(true);
|
|
388
|
-
this.alertService.addAlert("Product saved successfully!", "success");
|
|
389
|
-
},
|
|
390
|
-
error: () => (this.isWorking = false),
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
/**
|
|
394
|
-
* Method to evaluate form fields
|
|
395
|
-
*/
|
|
396
|
-
isFieldValid(field) {
|
|
397
|
-
return this.formValidatorService.isFieldValid(field, this.productForm);
|
|
398
|
-
}
|
|
399
|
-
/**
|
|
400
|
-
* Method to find error in form fields
|
|
401
|
-
*/
|
|
402
|
-
getErrorMessage(field) {
|
|
403
|
-
return this.formValidatorService.getErrorMessage(field, this.productForm, errorMessages);
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* Checks displayed Form Fields array for form field and returns boolean result
|
|
407
|
-
*/
|
|
408
|
-
isFormFieldShown(fieldName) {
|
|
409
|
-
return (this.displayedFormFields.length > 0 &&
|
|
410
|
-
this.displayedFormFields.includes(fieldName));
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* Checks displayed Form Section array for form section and returns boolean result
|
|
414
|
-
*/
|
|
415
|
-
isFormSectionShown(sectionName) {
|
|
416
|
-
return (this.displayedFormSections.length > 0 &&
|
|
417
|
-
this.displayedFormSections.includes(sectionName));
|
|
418
|
-
}
|
|
419
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductFormComponent, deps: [{ token: ProductService }, { token: i2.FormBuilder }, { token: i1$1.FormValidatorService }, { token: i1$1.AlertService }, { token: i4.DatePipe }, { token: ProductFormService }], target: i0.ɵɵFactoryTarget.Component });
|
|
420
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ProductFormComponent, selector: "app-product-form", inputs: { product: "product", displayedFormFields: "displayedFormFields", displayedFormSections: "displayedFormSections" }, outputs: { saved: "saved", cancelled: "cancelled" }, ngImport: i0, template: "<form [formGroup]=\"productForm\" (submit)=\"save()\">\n <h3 class=\"text-center\">{{ product?.id ? \"Update\" : \"Create\" }} Product</h3>\n <div fxLayout=\"column\">\n <div fxLayout=\"column\" *ngIf=\"isFormSectionShown('basic information')\">\n <h3><strong>Basic Information</strong></h3>\n <div fxLayout fxLayoutGap=\"0.5rem\">\n <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('name')\">\n <input matInput placeholder=\"Name\" formControlName=\"name\" required />\n <mat-error *ngIf=\"isFieldValid('name')\"\n >{{ getErrorMessage(\"name\") }}\n </mat-error>\n </mat-form-field>\n <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('product type')\">\n <mat-label>Product Type</mat-label>\n <app-searchable-selector\n apiUrl=\"api/product-types\"\n formControlName=\"type_id\"\n >\n </app-searchable-selector>\n <mat-error *ngIf=\"isFieldValid('type_id')\"\n >{{ getErrorMessage(\"type_id\") }}\n </mat-error>\n </mat-form-field>\n </div>\n <div fxLayout fxLayoutGap=\"0.5rem\">\n <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('sku')\">\n <input matInput placeholder=\"SKU\" formControlName=\"sku\" />\n <mat-error *ngIf=\"isFieldValid('sku')\"\n >{{ getErrorMessage(\"sku\") }}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field fxFlex=\"50%\">\n <mat-label>Category</mat-label>\n <app-searchable-selector\n apiUrl=\"api/product-categories\"\n formControlName=\"category_ids\"\n [multiple]=\"true\"\n >\n </app-searchable-selector>\n <mat-error *ngIf=\"isFieldValid('category_ids')\">\n {{ getErrorMessage(\"category_ids\") }}\n </mat-error>\n </mat-form-field>\n </div>\n\n <div fxLayout fxLayoutGap=\"0.5rem\">\n <mat-form-field fxFlex=\"100%\" *ngIf=\"isFormFieldShown('description')\">\n <textarea\n matInput\n placeholder=\"Description\"\n formControlName=\"description\"\n ></textarea>\n </mat-form-field>\n </div>\n </div>\n\n <div fxLayout=\"column\" *ngIf=\"isFormSectionShown('inventory information')\">\n <h3><strong>Inventory Information</strong></h3>\n <div fxLayout fxLayoutGap=\"0.5rem\">\n <mat-form-field\n fxFlex=\"50%\"\n *ngIf=\"isFormFieldShown('product measure')\"\n >\n <mat-label>Measure</mat-label>\n <app-searchable-selector\n apiUrl=\"api/product-measures\"\n formControlName=\"measure_id\"\n >\n </app-searchable-selector>\n <mat-error *ngIf=\"isFieldValid('measure_id')\"\n >{{ getErrorMessage(\"measure_id\") }}\n </mat-error>\n </mat-form-field>\n <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('reorder point')\">\n <input\n matInput\n placeholder=\"Reorder Point\"\n formControlName=\"reorder_point\"\n type=\"number\"\n />\n <mat-error *ngIf=\"isFieldValid('reorder_point')\"\n >{{ getErrorMessage(\"reorder_point\") }}\n </mat-error>\n </mat-form-field>\n </div>\n <div fxLayout fxLayoutGap=\"0.5rem\">\n <mat-form-field\n fxFlex=\"50%\"\n *ngIf=\"isFormFieldShown('initial quantity')\"\n >\n <input\n matInput\n placeholder=\"Initial Quantity\"\n formControlName=\"initial_quantity\"\n />\n <mat-error *ngIf=\"isFieldValid('initial_quantity')\"\n >{{ getErrorMessage(\"initial_quantity\") }}\n </mat-error>\n </mat-form-field>\n <mat-form-field\n fxFlex=\"50%\"\n *ngIf=\"isFormFieldShown('initial quantity date')\"\n >\n <input\n matInput\n [matDatepicker]=\"pickerInitialQuantityDate\"\n placeholder=\"Initial Quantity Date\"\n formControlName=\"initial_quantity_date\"\n />\n <mat-datepicker-toggle\n matSuffix\n [for]=\"pickerInitialQuantityDate\"\n ></mat-datepicker-toggle>\n <mat-datepicker #pickerInitialQuantityDate></mat-datepicker>\n <mat-error *ngIf=\"isFieldValid('initial_quantity_date')\"\n >{{ getErrorMessage(\"initial_quantity_date\") }}\n </mat-error>\n </mat-form-field>\n </div>\n </div>\n <div fxLayout=\"column\" *ngIf=\"isFormSectionShown('sales information')\">\n <h3><strong>Sale Information</strong></h3>\n <div fxLayout fxLayoutGap=\"0.5rem\">\n <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('sales price')\">\n <input\n matInput\n placeholder=\"Selling Price\"\n formControlName=\"sale_price\"\n required\n type=\"number\"\n step=\"any\"\n />\n <mat-error *ngIf=\"isFieldValid('sale_price')\"\n >{{ getErrorMessage(\"sale_price\") }}\n </mat-error>\n </mat-form-field>\n <mat-form-field\n fxFlex=\"50%\"\n *ngIf=\"isFormFieldShown('condition types')\"\n >\n <mat-label>Condition</mat-label>\n <app-searchable-selector\n apiUrl=\"api/condition-types\"\n formControlName=\"condition_type_id\"\n ></app-searchable-selector>\n </mat-form-field>\n </div>\n <div fxLayout fxLayoutGap=\"0.5rem\">\n <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('minimum price')\">\n <input\n matInput\n placeholder=\"Minimum Price\"\n formControlName=\"minimum_price\"\n required\n type=\"number\"\n step=\"any\"\n />\n <mat-error *ngIf=\"isFieldValid('minimum_price')\"\n >{{ getErrorMessage(\"minimum_price\") }}\n </mat-error>\n </mat-form-field>\n <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('maximum price')\">\n <input\n matInput\n placeholder=\"Maximum Price\"\n formControlName=\"maximum_price\"\n type=\"number\"\n step=\"any\"\n />\n </mat-form-field>\n </div>\n </div>\n <!-- <div fxLayout=\"column\" *ngIf=\"isFormSectionShown('accounts information')\">-->\n <!-- <h3><strong>Accounts Information</strong></h3>-->\n <!-- <div fxLayout fxLayoutGap=\"0.5rem\">-->\n <!-- <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('income account')\">-->\n <!-- <mat-label>Income Account</mat-label>-->\n <!-- <app-searchable-selector apiUrl=\"api/accounts\" formControlName=\"income_account_id\"> </app-searchable-selector>-->\n <!-- </mat-form-field>-->\n <!-- <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('expense account')\">-->\n <!-- <mat-label>Expense Account</mat-label>-->\n <!-- <app-searchable-selector apiUrl=\"api/accounts\" formControlName=\"expense_account_id\">-->\n <!-- </app-searchable-selector>-->\n <!-- </mat-form-field>-->\n <!-- </div>-->\n <!-- </div>-->\n <div fxFlex=\"100%\" fxLayout fxLayoutAlign=\"end\" fxLayoutGap=\"1rem\">\n <button\n [disabled]=\"isWorking\"\n mat-button\n class=\"mt-2\"\n type=\"button\"\n (click)=\"cancelled.emit(true)\"\n >\n Cancel\n </button>\n <button\n [disabled]=\"isWorking\"\n mat-raised-button\n color=\"primary\"\n class=\"mt-2\"\n type=\"submit\"\n >\n Save\n </button>\n </div>\n </div>\n</form>\n", dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i1$1.SearchableSelectorComponent, selector: "app-searchable-selector", inputs: ["valueField", "titleField", "subtitleField", "apiUrl", "multiple", "selectedValue", "enableSearch", "add", "addConfig", "edit", "editConfig", "sort", "sortBy", "searchField", "itemComponent", "items", "apiDataProperty", "cache", "perPage", "inDataSearch", "panelWidth", "focusSearchOnOpen", "required", "disabled", "value"], outputs: ["selectedValueChange", "selectionChange", "itemsChange"] }, { kind: "component", type: i7.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i7$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i9.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i9.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i9.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "directive", type: i10.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i10.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i10.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i10.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], preserveWhitespaces: true });
|
|
421
|
-
}
|
|
422
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductFormComponent, decorators: [{
|
|
423
|
-
type: Component,
|
|
424
|
-
args: [{ selector: "app-product-form", template: "<form [formGroup]=\"productForm\" (submit)=\"save()\">\n <h3 class=\"text-center\">{{ product?.id ? \"Update\" : \"Create\" }} Product</h3>\n <div fxLayout=\"column\">\n <div fxLayout=\"column\" *ngIf=\"isFormSectionShown('basic information')\">\n <h3><strong>Basic Information</strong></h3>\n <div fxLayout fxLayoutGap=\"0.5rem\">\n <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('name')\">\n <input matInput placeholder=\"Name\" formControlName=\"name\" required />\n <mat-error *ngIf=\"isFieldValid('name')\"\n >{{ getErrorMessage(\"name\") }}\n </mat-error>\n </mat-form-field>\n <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('product type')\">\n <mat-label>Product Type</mat-label>\n <app-searchable-selector\n apiUrl=\"api/product-types\"\n formControlName=\"type_id\"\n >\n </app-searchable-selector>\n <mat-error *ngIf=\"isFieldValid('type_id')\"\n >{{ getErrorMessage(\"type_id\") }}\n </mat-error>\n </mat-form-field>\n </div>\n <div fxLayout fxLayoutGap=\"0.5rem\">\n <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('sku')\">\n <input matInput placeholder=\"SKU\" formControlName=\"sku\" />\n <mat-error *ngIf=\"isFieldValid('sku')\"\n >{{ getErrorMessage(\"sku\") }}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field fxFlex=\"50%\">\n <mat-label>Category</mat-label>\n <app-searchable-selector\n apiUrl=\"api/product-categories\"\n formControlName=\"category_ids\"\n [multiple]=\"true\"\n >\n </app-searchable-selector>\n <mat-error *ngIf=\"isFieldValid('category_ids')\">\n {{ getErrorMessage(\"category_ids\") }}\n </mat-error>\n </mat-form-field>\n </div>\n\n <div fxLayout fxLayoutGap=\"0.5rem\">\n <mat-form-field fxFlex=\"100%\" *ngIf=\"isFormFieldShown('description')\">\n <textarea\n matInput\n placeholder=\"Description\"\n formControlName=\"description\"\n ></textarea>\n </mat-form-field>\n </div>\n </div>\n\n <div fxLayout=\"column\" *ngIf=\"isFormSectionShown('inventory information')\">\n <h3><strong>Inventory Information</strong></h3>\n <div fxLayout fxLayoutGap=\"0.5rem\">\n <mat-form-field\n fxFlex=\"50%\"\n *ngIf=\"isFormFieldShown('product measure')\"\n >\n <mat-label>Measure</mat-label>\n <app-searchable-selector\n apiUrl=\"api/product-measures\"\n formControlName=\"measure_id\"\n >\n </app-searchable-selector>\n <mat-error *ngIf=\"isFieldValid('measure_id')\"\n >{{ getErrorMessage(\"measure_id\") }}\n </mat-error>\n </mat-form-field>\n <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('reorder point')\">\n <input\n matInput\n placeholder=\"Reorder Point\"\n formControlName=\"reorder_point\"\n type=\"number\"\n />\n <mat-error *ngIf=\"isFieldValid('reorder_point')\"\n >{{ getErrorMessage(\"reorder_point\") }}\n </mat-error>\n </mat-form-field>\n </div>\n <div fxLayout fxLayoutGap=\"0.5rem\">\n <mat-form-field\n fxFlex=\"50%\"\n *ngIf=\"isFormFieldShown('initial quantity')\"\n >\n <input\n matInput\n placeholder=\"Initial Quantity\"\n formControlName=\"initial_quantity\"\n />\n <mat-error *ngIf=\"isFieldValid('initial_quantity')\"\n >{{ getErrorMessage(\"initial_quantity\") }}\n </mat-error>\n </mat-form-field>\n <mat-form-field\n fxFlex=\"50%\"\n *ngIf=\"isFormFieldShown('initial quantity date')\"\n >\n <input\n matInput\n [matDatepicker]=\"pickerInitialQuantityDate\"\n placeholder=\"Initial Quantity Date\"\n formControlName=\"initial_quantity_date\"\n />\n <mat-datepicker-toggle\n matSuffix\n [for]=\"pickerInitialQuantityDate\"\n ></mat-datepicker-toggle>\n <mat-datepicker #pickerInitialQuantityDate></mat-datepicker>\n <mat-error *ngIf=\"isFieldValid('initial_quantity_date')\"\n >{{ getErrorMessage(\"initial_quantity_date\") }}\n </mat-error>\n </mat-form-field>\n </div>\n </div>\n <div fxLayout=\"column\" *ngIf=\"isFormSectionShown('sales information')\">\n <h3><strong>Sale Information</strong></h3>\n <div fxLayout fxLayoutGap=\"0.5rem\">\n <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('sales price')\">\n <input\n matInput\n placeholder=\"Selling Price\"\n formControlName=\"sale_price\"\n required\n type=\"number\"\n step=\"any\"\n />\n <mat-error *ngIf=\"isFieldValid('sale_price')\"\n >{{ getErrorMessage(\"sale_price\") }}\n </mat-error>\n </mat-form-field>\n <mat-form-field\n fxFlex=\"50%\"\n *ngIf=\"isFormFieldShown('condition types')\"\n >\n <mat-label>Condition</mat-label>\n <app-searchable-selector\n apiUrl=\"api/condition-types\"\n formControlName=\"condition_type_id\"\n ></app-searchable-selector>\n </mat-form-field>\n </div>\n <div fxLayout fxLayoutGap=\"0.5rem\">\n <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('minimum price')\">\n <input\n matInput\n placeholder=\"Minimum Price\"\n formControlName=\"minimum_price\"\n required\n type=\"number\"\n step=\"any\"\n />\n <mat-error *ngIf=\"isFieldValid('minimum_price')\"\n >{{ getErrorMessage(\"minimum_price\") }}\n </mat-error>\n </mat-form-field>\n <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('maximum price')\">\n <input\n matInput\n placeholder=\"Maximum Price\"\n formControlName=\"maximum_price\"\n type=\"number\"\n step=\"any\"\n />\n </mat-form-field>\n </div>\n </div>\n <!-- <div fxLayout=\"column\" *ngIf=\"isFormSectionShown('accounts information')\">-->\n <!-- <h3><strong>Accounts Information</strong></h3>-->\n <!-- <div fxLayout fxLayoutGap=\"0.5rem\">-->\n <!-- <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('income account')\">-->\n <!-- <mat-label>Income Account</mat-label>-->\n <!-- <app-searchable-selector apiUrl=\"api/accounts\" formControlName=\"income_account_id\"> </app-searchable-selector>-->\n <!-- </mat-form-field>-->\n <!-- <mat-form-field fxFlex=\"50%\" *ngIf=\"isFormFieldShown('expense account')\">-->\n <!-- <mat-label>Expense Account</mat-label>-->\n <!-- <app-searchable-selector apiUrl=\"api/accounts\" formControlName=\"expense_account_id\">-->\n <!-- </app-searchable-selector>-->\n <!-- </mat-form-field>-->\n <!-- </div>-->\n <!-- </div>-->\n <div fxFlex=\"100%\" fxLayout fxLayoutAlign=\"end\" fxLayoutGap=\"1rem\">\n <button\n [disabled]=\"isWorking\"\n mat-button\n class=\"mt-2\"\n type=\"button\"\n (click)=\"cancelled.emit(true)\"\n >\n Cancel\n </button>\n <button\n [disabled]=\"isWorking\"\n mat-raised-button\n color=\"primary\"\n class=\"mt-2\"\n type=\"submit\"\n >\n Save\n </button>\n </div>\n </div>\n</form>\n" }]
|
|
425
|
-
}], ctorParameters: () => [{ type: ProductService }, { type: i2.FormBuilder }, { type: i1$1.FormValidatorService }, { type: i1$1.AlertService }, { type: i4.DatePipe }, { type: ProductFormService }], propDecorators: { saved: [{
|
|
426
|
-
type: Output
|
|
427
|
-
}], cancelled: [{
|
|
428
|
-
type: Output
|
|
429
|
-
}], product: [{
|
|
430
|
-
type: Input
|
|
431
|
-
}], displayedFormFields: [{
|
|
432
|
-
type: Input
|
|
433
|
-
}], displayedFormSections: [{
|
|
434
|
-
type: Input
|
|
435
|
-
}] } });
|
|
436
|
-
|
|
437
|
-
class ProductFormButtonComponent {
|
|
438
|
-
matDialog;
|
|
439
|
-
productFormService;
|
|
440
|
-
product;
|
|
441
|
-
saved = new EventEmitter();
|
|
442
|
-
constructor(matDialog, productFormService) {
|
|
443
|
-
this.matDialog = matDialog;
|
|
444
|
-
this.productFormService = productFormService;
|
|
445
|
-
}
|
|
446
|
-
showForm(templateRef) {
|
|
447
|
-
this.matDialog.open(templateRef, { width: "600px" });
|
|
448
|
-
}
|
|
449
|
-
/**
|
|
450
|
-
* Handle on product saved event.
|
|
451
|
-
*
|
|
452
|
-
* @param product
|
|
453
|
-
*/
|
|
454
|
-
onProductSaved(product) {
|
|
455
|
-
this.saved.emit(product);
|
|
456
|
-
this.matDialog?.closeAll();
|
|
457
|
-
this.productFormService.listUpdated(true);
|
|
458
|
-
}
|
|
459
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductFormButtonComponent, deps: [{ token: i1.MatDialog }, { token: ProductFormService }], target: i0.ɵɵFactoryTarget.Component });
|
|
460
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ProductFormButtonComponent, selector: "app-product-form-button", inputs: { product: "product" }, outputs: { saved: "saved" }, ngImport: i0, template: "<mat-icon\n color=\"primary\"\n class=\"cursor-pointer\"\n [class.text-secondary]=\"product\"\n (click)=\"showForm(addProductForm)\"\n>\n {{ product ? \"edit\" : \"add\" }}\n</mat-icon>\n\n<ng-template #addProductForm>\n <app-product-form\n [product]=\"product\"\n mat-dialog-content\n (saved)=\"onProductSaved($event)\"\n (cancelled)=\"matDialog.closeAll()\"\n ></app-product-form>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ProductFormComponent, selector: "app-product-form", inputs: ["product", "displayedFormFields", "displayedFormSections"], outputs: ["saved", "cancelled"] }], preserveWhitespaces: true });
|
|
461
|
-
}
|
|
462
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductFormButtonComponent, decorators: [{
|
|
463
|
-
type: Component,
|
|
464
|
-
args: [{ selector: "app-product-form-button", template: "<mat-icon\n color=\"primary\"\n class=\"cursor-pointer\"\n [class.text-secondary]=\"product\"\n (click)=\"showForm(addProductForm)\"\n>\n {{ product ? \"edit\" : \"add\" }}\n</mat-icon>\n\n<ng-template #addProductForm>\n <app-product-form\n [product]=\"product\"\n mat-dialog-content\n (saved)=\"onProductSaved($event)\"\n (cancelled)=\"matDialog.closeAll()\"\n ></app-product-form>\n</ng-template>\n" }]
|
|
465
|
-
}], ctorParameters: () => [{ type: i1.MatDialog }, { type: ProductFormService }], propDecorators: { product: [{
|
|
466
|
-
type: Input
|
|
467
|
-
}], saved: [{
|
|
468
|
-
type: Output
|
|
469
|
-
}] } });
|
|
470
|
-
|
|
471
|
-
let ProductListComponent = class ProductListComponent {
|
|
472
|
-
fb;
|
|
473
|
-
dialog;
|
|
474
|
-
activatedRoute;
|
|
475
|
-
productService;
|
|
476
|
-
requestHelperService;
|
|
477
|
-
productFormService;
|
|
478
|
-
filterForm;
|
|
479
|
-
lastPage;
|
|
480
|
-
page = 1;
|
|
481
|
-
perPage = 25;
|
|
482
|
-
totalItems = 0;
|
|
483
|
-
currentPage = 1;
|
|
484
|
-
num_items = 25;
|
|
485
|
-
routeFilters;
|
|
486
|
-
products = [];
|
|
487
|
-
dataSource = new MatTableDataSource();
|
|
488
|
-
isLoading = false;
|
|
489
|
-
columnConfig = [
|
|
490
|
-
{ label: '#', def: '#', isSelected: true, isEditable: true },
|
|
491
|
-
{ label: 'Name', def: 'name', isSelected: true, isEditable: true },
|
|
492
|
-
{ label: 'SKU', def: 'sku', isSelected: true, isEditable: true },
|
|
493
|
-
{ label: 'Categories', def: 'categories', isSelected: true, isEditable: true },
|
|
494
|
-
{ label: 'Initial Quantity', def: 'initial_quantity', isSelected: true, isEditable: true },
|
|
495
|
-
{ label: 'Reorder Point', def: 'reorder_point', isSelected: true, isEditable: true },
|
|
496
|
-
{ label: 'Stock Receipts', def: 'stock_receipts', isSelected: true, isEditable: true },
|
|
497
|
-
{ label: 'Stock Issuances', def: 'stock_issuances', isSelected: true, isEditable: true },
|
|
498
|
-
{ label: 'On Hand', def: 'on_hand', isSelected: true, isEditable: true },
|
|
499
|
-
{ label: 'Sale Price', def: 'sale_price', isSelected: true, isEditable: true },
|
|
500
|
-
{ label: 'Income Account', def: 'income_account', isSelected: false, isEditable: true },
|
|
501
|
-
{ label: 'Expense Account', def: 'expense_account', isSelected: false, isEditable: true },
|
|
502
|
-
{ label: 'Creator', def: 'creator', isSelected: false, isEditable: true },
|
|
503
|
-
{ label: 'Actions', def: 'Actions', isSelected: true, isEditable: true },
|
|
504
|
-
];
|
|
505
|
-
selectedColumns = this.columnConfig.filter(col => col.isSelected);
|
|
506
|
-
get displayedColumns() {
|
|
507
|
-
return this.selectedColumns.map(col => col.def);
|
|
508
|
-
}
|
|
509
|
-
importId;
|
|
510
|
-
constructor(fb, dialog, activatedRoute, productService, requestHelperService, productFormService) {
|
|
511
|
-
this.fb = fb;
|
|
512
|
-
this.dialog = dialog;
|
|
513
|
-
this.activatedRoute = activatedRoute;
|
|
514
|
-
this.productService = productService;
|
|
515
|
-
this.requestHelperService = requestHelperService;
|
|
516
|
-
this.productFormService = productFormService;
|
|
517
|
-
this.filterForm = this.fb.group({
|
|
518
|
-
search: [""],
|
|
519
|
-
category_ids: [""],
|
|
520
|
-
type_ids: [""],
|
|
521
|
-
income_account_ids: [""],
|
|
522
|
-
expense_account_ids: [""],
|
|
523
|
-
sort_by: [""],
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
ngOnInit() {
|
|
527
|
-
if (this.activatedRoute.snapshot.params?.["import_id"]) {
|
|
528
|
-
this.importId = parseInt(this.activatedRoute.snapshot.params?.["import_id"]);
|
|
529
|
-
}
|
|
530
|
-
// update form with URL query params
|
|
531
|
-
this.requestHelperService.updateFormWithQueryParams(this.filterForm, {
|
|
532
|
-
type_ids: { multiple: true },
|
|
533
|
-
category_ids: { multiple: true },
|
|
534
|
-
income_account_ids: { multiple: true },
|
|
535
|
-
expense_account_ids: { multiple: true },
|
|
536
|
-
});
|
|
537
|
-
// Update URL query params on filter change
|
|
538
|
-
this.filterForm.valueChanges.pipe(debounceTime(800)).subscribe(() => {
|
|
539
|
-
this.requestHelperService.updateQueryParams(this.requestHelperService.convertToFormData({
|
|
540
|
-
...this.filterForm.value,
|
|
541
|
-
}));
|
|
542
|
-
});
|
|
543
|
-
// fetch task on params change
|
|
544
|
-
this.activatedRoute.queryParams
|
|
545
|
-
.pipe(debounceTime(800))
|
|
546
|
-
.subscribe(() => this.reload());
|
|
547
|
-
// listen form product add or update event and reload.
|
|
548
|
-
this.productFormService.isListUpdated().subscribe((val) => {
|
|
549
|
-
if (val && !this.isLoading) {
|
|
550
|
-
this.reload();
|
|
551
|
-
}
|
|
552
|
-
});
|
|
553
|
-
}
|
|
554
|
-
loadData() {
|
|
555
|
-
let params = {
|
|
556
|
-
...this.requestHelperService.convertToFormData(this.filterForm.value),
|
|
557
|
-
};
|
|
558
|
-
params.page = this.page;
|
|
559
|
-
params.perPage = this.perPage;
|
|
560
|
-
params.num_items = this.num_items + "|" + this.currentPage;
|
|
561
|
-
params.with = "categories,lastStockReceipt,lastStockIssuance,creator";
|
|
562
|
-
if (this.importId) {
|
|
563
|
-
params.import_id = this.importId;
|
|
564
|
-
}
|
|
565
|
-
this.isLoading = true;
|
|
566
|
-
this.productService.index(params).subscribe({
|
|
567
|
-
next: (res) => {
|
|
568
|
-
this.isLoading = false;
|
|
569
|
-
this.dataSource = new MatTableDataSource(this.dataSource.data.concat(res?.data));
|
|
570
|
-
this.totalItems = res.total;
|
|
571
|
-
// stop reloading data once data loaded.
|
|
572
|
-
this.productFormService.listUpdated(false);
|
|
573
|
-
},
|
|
574
|
-
error: () => (this.isLoading = false),
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
reload() {
|
|
578
|
-
if (this.isLoading)
|
|
579
|
-
return;
|
|
580
|
-
this.dataSource = new MatTableDataSource();
|
|
581
|
-
this.currentPage = 1;
|
|
582
|
-
this.loadData();
|
|
583
|
-
}
|
|
584
|
-
modifyProduct(model) {
|
|
585
|
-
const dialogRef = this.dialog.open(ProductFormComponent, {
|
|
586
|
-
width: "600px",
|
|
587
|
-
data: {
|
|
588
|
-
details: model,
|
|
589
|
-
},
|
|
590
|
-
});
|
|
591
|
-
dialogRef.afterClosed().subscribe((result) => {
|
|
592
|
-
if (result) {
|
|
593
|
-
this.reload();
|
|
594
|
-
}
|
|
595
|
-
});
|
|
596
|
-
}
|
|
597
|
-
assignFilter(column, direction) {
|
|
598
|
-
if (column) {
|
|
599
|
-
return this.filterForm.get("sort_by")?.setValue(column + "|" + direction);
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
sortColumn(event) {
|
|
603
|
-
var direction = event.direction.toString().toUpperCase();
|
|
604
|
-
this.assignFilter(event.active, direction);
|
|
605
|
-
}
|
|
606
|
-
onScroll() {
|
|
607
|
-
if (this.totalItems > this.dataSource.data.length) {
|
|
608
|
-
this.currentPage += 1;
|
|
609
|
-
this.loadData();
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductListComponent, deps: [{ token: i2.FormBuilder }, { token: i1.MatDialog }, { token: i2$1.ActivatedRoute }, { token: ProductService }, { token: i1$1.RequestHelperService }, { token: ProductFormService }], target: i0.ɵɵFactoryTarget.Component });
|
|
613
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ProductListComponent, selector: "app-product-list", ngImport: i0, template: "<mat-card class=\"mb-3\">\n <mat-card-content>\n <form\n [formGroup]=\"filterForm\"\n class=\"d-flex justify-content-between align-items-center gap-2\"\n >\n <div class=\"d-flex justify-content-center align-items-center gap-2\">\n <h3 class=\"mb-0\">Products</h3>\n <app-product-form-button class=\"mt-2\"></app-product-form-button>\n <span matTooltip=\"Import\" routerLink=\"import\" class=\"cursor-pointer mt-1 material-symbols-outlined\">\n file_save\n </span>\n <app-column-selector\n mode=\"icon\"\n class=\"mb-2 d-print-none\"\n [columnConfigs]=\"columnConfig\"\n [(selectedColumns)]=\"selectedColumns\"\n ></app-column-selector>\n </div>\n\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <mat-form-field style=\"width: 120px\">\n <input matInput placeholder=\"Product\" formControlName=\"search\" />\n </mat-form-field>\n\n <mat-form-field style=\"width: 120px\">\n <mat-label>Category</mat-label>\n <app-searchable-selector\n apiUrl=\"api/product-categories\"\n formControlName=\"category_ids\"\n [multiple]=\"true\"\n >\n </app-searchable-selector>\n </mat-form-field>\n\n <mat-form-field style=\"width: 120px\">\n <mat-label>Type</mat-label>\n <app-searchable-selector\n apiUrl=\"api/product-types\"\n formControlName=\"type_ids\"\n titleField=\"title\"\n [multiple]=\"true\"\n >\n </app-searchable-selector>\n </mat-form-field>\n <!-- <mat-form-field style=\"width: 150px\">-->\n <!-- <mat-label>Income Account</mat-label>-->\n <!-- <app-searchable-selector-->\n <!-- apiUrl=\"api/accounts\"-->\n <!-- formControlName=\"income_account_ids\"-->\n <!-- titleField=\"title\"-->\n <!-- [multiple]=\"true\"-->\n <!-- >-->\n <!-- </app-searchable-selector>-->\n <!-- </mat-form-field>-->\n <!-- <mat-form-field style=\"width: 150px\">-->\n <!-- <mat-label>Expense Account</mat-label>-->\n <!-- <app-searchable-selector-->\n <!-- apiUrl=\"api/accounts\"-->\n <!-- formControlName=\"expense_account_ids\"-->\n <!-- titleField=\"title\"-->\n <!-- [multiple]=\"true\"-->\n <!-- >-->\n <!-- </app-searchable-selector>-->\n <!-- </mat-form-field>-->\n </div>\n </form>\n </mat-card-content>\n</mat-card>\n\n<mat-card>\n <mat-card-content class=\"p-0\">\n <table\n mat-table\n [dataSource]=\"dataSource\"\n class=\"w-100\"\n infiniteScroll\n [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\"\n (scrolled)=\"onScroll()\"\n [fromRoot]=\"true\"\n matSort\n (matSortChange)=\"sortColumn($event)\"\n matSortDisableClear=\"true\"\n aria-describedby=\"Products List\"\n >\n <!-- # Column -->\n <ng-container matColumnDef=\"#\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <!-- Name Column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Name</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"d-flex flex-column gap-1\">\n <a class=\"text-decoration-none text-dark\" [routerLink]=\"[element?.id, 'view']\">{{ element.name }}</a>\n <small class=\"text-secondary\" *ngIf=\"element.type\">{{ element.type?.title }}</small>\n </div>\n </td>\n </ng-container>\n\n <!-- Categories Column -->\n <ng-container matColumnDef=\"categories\">\n <th mat-header-cell *matHeaderCellDef>Categories</th>\n <td mat-cell *matCellDef=\"let element\" style=\"max-width: 200px\">\n <div\n *ngIf=\"element?.categories?.length > 0\"\n class=\"d-flex justify-content-start align-items-center gap-1 flex-wrap\"\n >\n <span\n class=\"badge bg-secondary\"\n *ngFor=\"let category of element?.categories\"\n >\n {{ category?.title }}\n </span>\n </div>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element.sku }}</td>\n </ng-container>\n\n <!-- Initial Quantity Column -->\n <ng-container matColumnDef=\"initial_quantity\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>\n Initial Quantity\n </th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element.initial_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.initial_quantity_date\">\n on {{ element?.initial_quantity_date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- Stock Receipts Column -->\n <ng-container matColumnDef=\"stock_receipts\">\n <th mat-header-cell mat-sort-header=\"stock_receipts_sum_quantity\" *matHeaderCellDef>\n Stock Receipts\n </th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element?.stock_receipts_sum_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.last_stock_receipt\">\n last added on {{ element?.last_stock_receipt?.date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- Stock Issuances Column -->\n <ng-container matColumnDef=\"stock_issuances\">\n <th mat-header-cell mat-sort-header=\"stock_issuances_sum_quantity\" *matHeaderCellDef>\n Stock Issuances\n </th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element?.stock_issuances_sum_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.last_stock_issuance\">\n last issued on {{ element?.last_stock_issuance?.date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- On Hand Column -->\n <ng-container matColumnDef=\"on_hand\">\n <th mat-header-cell mat-sort-header=\"stock_balance\" *matHeaderCellDef>On Hand</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.stock_balance }}\n </td>\n </ng-container>\n\n <!-- Reorder Point Column -->\n <ng-container matColumnDef=\"reorder_point\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Reorder Point</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.reorder_point }}\n </td>\n </ng-container>\n\n <!-- Selling Price Column -->\n <ng-container matColumnDef=\"sale_price\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Selling Price</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.sale_price | currency }}\n </td>\n </ng-container>\n\n <!-- Income Account Column -->\n <ng-container matColumnDef=\"income_account\">\n <th mat-header-cell *matHeaderCellDef>Income Account</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.income_account?.title }}\n </td>\n </ng-container>\n\n <!-- Expense Account Column -->\n <ng-container matColumnDef=\"expense_account\">\n <th mat-header-cell *matHeaderCellDef>Expense Account</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.expense_account?.title }}\n </td>\n </ng-container>\n\n <!-- Creator Column -->\n <ng-container matColumnDef=\"creator\">\n <th mat-header-cell *matHeaderCellDef>Creator</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element?.creator?.name }}</p>\n <small class=\"text-secondary\">{{ element?.created_at | date }}</small>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"Actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"text-secondary d-flex gap-1\">\n <app-product-form-button\n [product]=\"element\"\n ></app-product-form-button>\n <mat-icon\n class=\"cursor-pointer\"\n matTooltip=\"View\"\n [routerLink]=\"[element.id, 'view']\"\n routerLinkActive=\"route-link-active\"\n >\n remove_red_eye\n </mat-icon>\n\n <app-stock-receipt-form-button\n [product]=\"element\"\n (saved)=\"reload()\"\n ></app-stock-receipt-form-button>\n\n <app-stock-issue-form-button\n [product]=\"element\"\n (saved)=\"reload()\"\n ></app-stock-issue-form-button>\n </div>\n </td>\n </ng-container>\n <tr\n mat-header-row\n *matHeaderRowDef=\"displayedColumns; sticky: true\"\n ></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isLoading\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>\n", dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i2$1.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: i1$1.SearchableSelectorComponent, selector: "app-searchable-selector", inputs: ["valueField", "titleField", "subtitleField", "apiUrl", "multiple", "selectedValue", "enableSearch", "add", "addConfig", "edit", "editConfig", "sort", "sortBy", "searchField", "itemComponent", "items", "apiDataProperty", "cache", "perPage", "inDataSearch", "panelWidth", "focusSearchOnOpen", "required", "disabled", "value"], outputs: ["selectedValueChange", "selectionChange", "itemsChange"] }, { kind: "component", type: StockReceiptFormButtonComponent, selector: "app-stock-receipt-form-button", inputs: ["product", "stockReceipt", "icon"], outputs: ["saved"] }, { kind: "component", type: StockIssueFormButtonComponent, selector: "app-stock-issue-form-button", inputs: ["product", "stockIssuance", "icon", "issuableType", "issuableId"], outputs: ["saved"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i5.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i5.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i6$1.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6$1.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6$1.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6$1.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i6$1.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6$1.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6$1.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6$1.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6$1.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6$1.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i3$2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3$2.MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: i2$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i7$2.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: i10$2.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i1$1.ColumnSelectorComponent, selector: "app-column-selector", inputs: ["label", "mode", "columnConfigs", "selectedColumns"], outputs: ["selectedColumnsChange", "displayedColumnsChange"] }, { kind: "component", type: ProductFormButtonComponent, selector: "app-product-form-button", inputs: ["product"], outputs: ["saved"] }, { kind: "pipe", type: i4.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i4.DatePipe, name: "date" }], preserveWhitespaces: true });
|
|
614
|
-
};
|
|
615
|
-
ProductListComponent = __decorate([
|
|
616
|
-
UntilDestroy()
|
|
617
|
-
], ProductListComponent);
|
|
618
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductListComponent, decorators: [{
|
|
619
|
-
type: Component,
|
|
620
|
-
args: [{ selector: "app-product-list", template: "<mat-card class=\"mb-3\">\n <mat-card-content>\n <form\n [formGroup]=\"filterForm\"\n class=\"d-flex justify-content-between align-items-center gap-2\"\n >\n <div class=\"d-flex justify-content-center align-items-center gap-2\">\n <h3 class=\"mb-0\">Products</h3>\n <app-product-form-button class=\"mt-2\"></app-product-form-button>\n <span matTooltip=\"Import\" routerLink=\"import\" class=\"cursor-pointer mt-1 material-symbols-outlined\">\n file_save\n </span>\n <app-column-selector\n mode=\"icon\"\n class=\"mb-2 d-print-none\"\n [columnConfigs]=\"columnConfig\"\n [(selectedColumns)]=\"selectedColumns\"\n ></app-column-selector>\n </div>\n\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <mat-form-field style=\"width: 120px\">\n <input matInput placeholder=\"Product\" formControlName=\"search\" />\n </mat-form-field>\n\n <mat-form-field style=\"width: 120px\">\n <mat-label>Category</mat-label>\n <app-searchable-selector\n apiUrl=\"api/product-categories\"\n formControlName=\"category_ids\"\n [multiple]=\"true\"\n >\n </app-searchable-selector>\n </mat-form-field>\n\n <mat-form-field style=\"width: 120px\">\n <mat-label>Type</mat-label>\n <app-searchable-selector\n apiUrl=\"api/product-types\"\n formControlName=\"type_ids\"\n titleField=\"title\"\n [multiple]=\"true\"\n >\n </app-searchable-selector>\n </mat-form-field>\n <!-- <mat-form-field style=\"width: 150px\">-->\n <!-- <mat-label>Income Account</mat-label>-->\n <!-- <app-searchable-selector-->\n <!-- apiUrl=\"api/accounts\"-->\n <!-- formControlName=\"income_account_ids\"-->\n <!-- titleField=\"title\"-->\n <!-- [multiple]=\"true\"-->\n <!-- >-->\n <!-- </app-searchable-selector>-->\n <!-- </mat-form-field>-->\n <!-- <mat-form-field style=\"width: 150px\">-->\n <!-- <mat-label>Expense Account</mat-label>-->\n <!-- <app-searchable-selector-->\n <!-- apiUrl=\"api/accounts\"-->\n <!-- formControlName=\"expense_account_ids\"-->\n <!-- titleField=\"title\"-->\n <!-- [multiple]=\"true\"-->\n <!-- >-->\n <!-- </app-searchable-selector>-->\n <!-- </mat-form-field>-->\n </div>\n </form>\n </mat-card-content>\n</mat-card>\n\n<mat-card>\n <mat-card-content class=\"p-0\">\n <table\n mat-table\n [dataSource]=\"dataSource\"\n class=\"w-100\"\n infiniteScroll\n [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\"\n (scrolled)=\"onScroll()\"\n [fromRoot]=\"true\"\n matSort\n (matSortChange)=\"sortColumn($event)\"\n matSortDisableClear=\"true\"\n aria-describedby=\"Products List\"\n >\n <!-- # Column -->\n <ng-container matColumnDef=\"#\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <!-- Name Column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Name</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"d-flex flex-column gap-1\">\n <a class=\"text-decoration-none text-dark\" [routerLink]=\"[element?.id, 'view']\">{{ element.name }}</a>\n <small class=\"text-secondary\" *ngIf=\"element.type\">{{ element.type?.title }}</small>\n </div>\n </td>\n </ng-container>\n\n <!-- Categories Column -->\n <ng-container matColumnDef=\"categories\">\n <th mat-header-cell *matHeaderCellDef>Categories</th>\n <td mat-cell *matCellDef=\"let element\" style=\"max-width: 200px\">\n <div\n *ngIf=\"element?.categories?.length > 0\"\n class=\"d-flex justify-content-start align-items-center gap-1 flex-wrap\"\n >\n <span\n class=\"badge bg-secondary\"\n *ngFor=\"let category of element?.categories\"\n >\n {{ category?.title }}\n </span>\n </div>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element.sku }}</td>\n </ng-container>\n\n <!-- Initial Quantity Column -->\n <ng-container matColumnDef=\"initial_quantity\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>\n Initial Quantity\n </th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element.initial_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.initial_quantity_date\">\n on {{ element?.initial_quantity_date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- Stock Receipts Column -->\n <ng-container matColumnDef=\"stock_receipts\">\n <th mat-header-cell mat-sort-header=\"stock_receipts_sum_quantity\" *matHeaderCellDef>\n Stock Receipts\n </th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element?.stock_receipts_sum_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.last_stock_receipt\">\n last added on {{ element?.last_stock_receipt?.date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- Stock Issuances Column -->\n <ng-container matColumnDef=\"stock_issuances\">\n <th mat-header-cell mat-sort-header=\"stock_issuances_sum_quantity\" *matHeaderCellDef>\n Stock Issuances\n </th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element?.stock_issuances_sum_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.last_stock_issuance\">\n last issued on {{ element?.last_stock_issuance?.date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- On Hand Column -->\n <ng-container matColumnDef=\"on_hand\">\n <th mat-header-cell mat-sort-header=\"stock_balance\" *matHeaderCellDef>On Hand</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.stock_balance }}\n </td>\n </ng-container>\n\n <!-- Reorder Point Column -->\n <ng-container matColumnDef=\"reorder_point\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Reorder Point</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.reorder_point }}\n </td>\n </ng-container>\n\n <!-- Selling Price Column -->\n <ng-container matColumnDef=\"sale_price\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Selling Price</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.sale_price | currency }}\n </td>\n </ng-container>\n\n <!-- Income Account Column -->\n <ng-container matColumnDef=\"income_account\">\n <th mat-header-cell *matHeaderCellDef>Income Account</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.income_account?.title }}\n </td>\n </ng-container>\n\n <!-- Expense Account Column -->\n <ng-container matColumnDef=\"expense_account\">\n <th mat-header-cell *matHeaderCellDef>Expense Account</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.expense_account?.title }}\n </td>\n </ng-container>\n\n <!-- Creator Column -->\n <ng-container matColumnDef=\"creator\">\n <th mat-header-cell *matHeaderCellDef>Creator</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element?.creator?.name }}</p>\n <small class=\"text-secondary\">{{ element?.created_at | date }}</small>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"Actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"text-secondary d-flex gap-1\">\n <app-product-form-button\n [product]=\"element\"\n ></app-product-form-button>\n <mat-icon\n class=\"cursor-pointer\"\n matTooltip=\"View\"\n [routerLink]=\"[element.id, 'view']\"\n routerLinkActive=\"route-link-active\"\n >\n remove_red_eye\n </mat-icon>\n\n <app-stock-receipt-form-button\n [product]=\"element\"\n (saved)=\"reload()\"\n ></app-stock-receipt-form-button>\n\n <app-stock-issue-form-button\n [product]=\"element\"\n (saved)=\"reload()\"\n ></app-stock-issue-form-button>\n </div>\n </td>\n </ng-container>\n <tr\n mat-header-row\n *matHeaderRowDef=\"displayedColumns; sticky: true\"\n ></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isLoading\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>\n" }]
|
|
621
|
-
}], ctorParameters: () => [{ type: i2.FormBuilder }, { type: i1.MatDialog }, { type: i2$1.ActivatedRoute }, { type: ProductService }, { type: i1$1.RequestHelperService }, { type: ProductFormService }] });
|
|
622
|
-
|
|
623
|
-
class ProductNavBarComponent {
|
|
624
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductNavBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
625
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ProductNavBarComponent, selector: "app-product-nav-bar", ngImport: i0, template: "<div>\n <router-outlet></router-outlet>\n</div>\n", dependencies: [{ kind: "directive", type: i2$1.RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }], preserveWhitespaces: true });
|
|
626
|
-
}
|
|
627
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductNavBarComponent, decorators: [{
|
|
628
|
-
type: Component,
|
|
629
|
-
args: [{ selector: "app-product-nav-bar", template: "<div>\n <router-outlet></router-outlet>\n</div>\n" }]
|
|
630
|
-
}] });
|
|
631
|
-
|
|
632
|
-
class ProductTaxService extends TechlifyServiceBaseClass {
|
|
633
|
-
constructor(httpService) {
|
|
634
|
-
super(httpService, "product-taxes");
|
|
635
|
-
}
|
|
636
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductTaxService, deps: [{ token: i1$1.HttpService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
637
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductTaxService, providedIn: "root" });
|
|
638
|
-
}
|
|
639
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductTaxService, decorators: [{
|
|
640
|
-
type: Injectable,
|
|
641
|
-
args: [{
|
|
642
|
-
providedIn: "root",
|
|
643
|
-
}]
|
|
644
|
-
}], ctorParameters: () => [{ type: i1$1.HttpService }] });
|
|
645
|
-
|
|
646
|
-
class ProductTaxFormButtonComponent extends TechlifyFormComponentInterface {
|
|
647
|
-
matDialog;
|
|
648
|
-
productTaxService;
|
|
649
|
-
formBuilder;
|
|
650
|
-
alertService;
|
|
651
|
-
product;
|
|
652
|
-
saved = new EventEmitter();
|
|
653
|
-
isSaving;
|
|
654
|
-
constructor(matDialog, productTaxService, formValidatorService, formBuilder, alertService) {
|
|
655
|
-
super(formValidatorService);
|
|
656
|
-
this.matDialog = matDialog;
|
|
657
|
-
this.productTaxService = productTaxService;
|
|
658
|
-
this.formBuilder = formBuilder;
|
|
659
|
-
this.alertService = alertService;
|
|
660
|
-
this.errorMessages = {
|
|
661
|
-
tax_id: {
|
|
662
|
-
required: "The tax field is required.",
|
|
663
|
-
},
|
|
664
|
-
};
|
|
665
|
-
this.form = this.formBuilder.group({
|
|
666
|
-
product_id: [""],
|
|
667
|
-
tax_id: ["", Validators.required],
|
|
668
|
-
});
|
|
669
|
-
}
|
|
670
|
-
ngOnInit() {
|
|
671
|
-
if (this.product) {
|
|
672
|
-
this.form.get("product_id")?.setValue(this.product?.id);
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
showForm(templateRef) {
|
|
676
|
-
this.matDialog.open(templateRef, { width: "400px" });
|
|
677
|
-
}
|
|
678
|
-
save() {
|
|
679
|
-
this.form.markAllAsTouched();
|
|
680
|
-
if (this.form.invalid) {
|
|
681
|
-
this.alertService.addAlert("Please check the form for errors.", "error");
|
|
682
|
-
return;
|
|
683
|
-
}
|
|
684
|
-
const data = { ...this.form.value };
|
|
685
|
-
const params = {
|
|
686
|
-
with: "tax.type",
|
|
687
|
-
};
|
|
688
|
-
this.isSaving = true;
|
|
689
|
-
this.productTaxService.store(data, params).subscribe({
|
|
690
|
-
next: (response) => {
|
|
691
|
-
this.isSaving = false;
|
|
692
|
-
this.matDialog.closeAll();
|
|
693
|
-
this.alertService.addAlert("Product tax saved successfully!", "success");
|
|
694
|
-
this.saved.emit(response?.item);
|
|
695
|
-
},
|
|
696
|
-
error: () => (this.isSaving = false),
|
|
697
|
-
});
|
|
698
|
-
}
|
|
699
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductTaxFormButtonComponent, deps: [{ token: i1.MatDialog }, { token: ProductTaxService }, { token: i1$1.FormValidatorService }, { token: i2.FormBuilder }, { token: i1$1.AlertService }], target: i0.ɵɵFactoryTarget.Component });
|
|
700
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ProductTaxFormButtonComponent, selector: "app-product-tax-form-button", inputs: { product: "product" }, outputs: { saved: "saved" }, usesInheritance: true, ngImport: i0, template: "<mat-icon\n color=\"primary\"\n class=\"cursor-pointer\"\n (click)=\"showForm(formTemplate)\"\n>\n add\n</mat-icon>\n\n<ng-template #formTemplate>\n <form\n [formGroup]=\"form\"\n (submit)=\"save()\"\n mat-dialog-content\n class=\"d-flex flex-column gap-2\"\n >\n <h3 class=\"text-dark\">Add tax for {{ product?.name }}</h3>\n <mat-form-field>\n <mat-label>Tax</mat-label>\n <app-searchable-selector\n formControlName=\"tax_id\"\n required\n apiUrl=\"api/taxes\"\n [enableSearch]=\"false\"\n ></app-searchable-selector>\n <mat-error *ngIf=\"isFieldValid('tax_id')\">\n {{ getErrorMessage(\"tax_id\") }}\n </mat-error>\n </mat-form-field>\n\n <div class=\"d-flex justify-content-end align-items-center gap-3\">\n <button\n [disabled]=\"isSaving\"\n type=\"submit\"\n mat-raised-button\n color=\"primary\"\n >\n Save\n </button>\n <button\n [disabled]=\"isSaving\"\n type=\"button\"\n mat-flat-button\n mat-dialog-close\n >\n Cancel\n </button>\n </div>\n </form>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i7.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i1$1.SearchableSelectorComponent, selector: "app-searchable-selector", inputs: ["valueField", "titleField", "subtitleField", "apiUrl", "multiple", "selectedValue", "enableSearch", "add", "addConfig", "edit", "editConfig", "sort", "sortBy", "searchField", "itemComponent", "items", "apiDataProperty", "cache", "perPage", "inDataSearch", "panelWidth", "focusSearchOnOpen", "required", "disabled", "value"], outputs: ["selectedValueChange", "selectionChange", "itemsChange"] }], preserveWhitespaces: true });
|
|
701
|
-
}
|
|
702
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductTaxFormButtonComponent, decorators: [{
|
|
703
|
-
type: Component,
|
|
704
|
-
args: [{ selector: "app-product-tax-form-button", template: "<mat-icon\n color=\"primary\"\n class=\"cursor-pointer\"\n (click)=\"showForm(formTemplate)\"\n>\n add\n</mat-icon>\n\n<ng-template #formTemplate>\n <form\n [formGroup]=\"form\"\n (submit)=\"save()\"\n mat-dialog-content\n class=\"d-flex flex-column gap-2\"\n >\n <h3 class=\"text-dark\">Add tax for {{ product?.name }}</h3>\n <mat-form-field>\n <mat-label>Tax</mat-label>\n <app-searchable-selector\n formControlName=\"tax_id\"\n required\n apiUrl=\"api/taxes\"\n [enableSearch]=\"false\"\n ></app-searchable-selector>\n <mat-error *ngIf=\"isFieldValid('tax_id')\">\n {{ getErrorMessage(\"tax_id\") }}\n </mat-error>\n </mat-form-field>\n\n <div class=\"d-flex justify-content-end align-items-center gap-3\">\n <button\n [disabled]=\"isSaving\"\n type=\"submit\"\n mat-raised-button\n color=\"primary\"\n >\n Save\n </button>\n <button\n [disabled]=\"isSaving\"\n type=\"button\"\n mat-flat-button\n mat-dialog-close\n >\n Cancel\n </button>\n </div>\n </form>\n</ng-template>\n" }]
|
|
705
|
-
}], ctorParameters: () => [{ type: i1.MatDialog }, { type: ProductTaxService }, { type: i1$1.FormValidatorService }, { type: i2.FormBuilder }, { type: i1$1.AlertService }], propDecorators: { product: [{
|
|
706
|
-
type: Input
|
|
707
|
-
}], saved: [{
|
|
708
|
-
type: Output
|
|
709
|
-
}] } });
|
|
710
|
-
|
|
711
|
-
class ProductTaxDeleteButtonComponent {
|
|
712
|
-
matDialog;
|
|
713
|
-
productTaxService;
|
|
714
|
-
alertService;
|
|
715
|
-
productTax;
|
|
716
|
-
deleted = new EventEmitter();
|
|
717
|
-
isDeleting;
|
|
718
|
-
constructor(matDialog, productTaxService, alertService) {
|
|
719
|
-
this.matDialog = matDialog;
|
|
720
|
-
this.productTaxService = productTaxService;
|
|
721
|
-
this.alertService = alertService;
|
|
722
|
-
}
|
|
723
|
-
/**
|
|
724
|
-
* Delete the product.
|
|
725
|
-
*/
|
|
726
|
-
delete() {
|
|
727
|
-
this.isDeleting = true;
|
|
728
|
-
this.productTaxService.delete(this.productTax).subscribe({
|
|
729
|
-
next: () => {
|
|
730
|
-
this.matDialog?.closeAll();
|
|
731
|
-
this.deleted.emit();
|
|
732
|
-
this.isDeleting = false;
|
|
733
|
-
this.alertService.addAlert("Product tax deleted successfully!", "success");
|
|
734
|
-
},
|
|
735
|
-
error: () => (this.isDeleting = false),
|
|
736
|
-
});
|
|
737
|
-
}
|
|
738
|
-
/**
|
|
739
|
-
* Show delete product dialog.
|
|
740
|
-
*
|
|
741
|
-
* @param templateRef
|
|
742
|
-
*/
|
|
743
|
-
showDeleteDialog(templateRef) {
|
|
744
|
-
this.matDialog.open(templateRef, { width: "500px" });
|
|
745
|
-
}
|
|
746
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductTaxDeleteButtonComponent, deps: [{ token: i1.MatDialog }, { token: ProductTaxService }, { token: i1$1.AlertService }], target: i0.ɵɵFactoryTarget.Component });
|
|
747
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ProductTaxDeleteButtonComponent, selector: "app-product-tax-delete-button", inputs: { productTax: "productTax" }, outputs: { deleted: "deleted" }, ngImport: i0, template: "<mat-icon\n class=\"cursor-pointer text-secondary\"\n (click)=\"showDeleteDialog(deleteConfirmDialog)\"\n>\n delete\n</mat-icon>\n\n<ng-template #deleteConfirmDialog>\n <h3 mat-dialog-title>Delete Product Tax</h3>\n <div mat-dialog-content>\n Are you sure? You want to delete the product tax?\n </div>\n <div mat-dialog-actions class=\"d-flex justify-content-end gap-1 mb-2\">\n <button\n [disabled]=\"isDeleting\"\n type=\"button\"\n mat-raised-button\n color=\"warn\"\n (click)=\"delete()\"\n >\n Delete\n </button>\n <button\n [disabled]=\"isDeleting\"\n type=\"button\"\n mat-flat-button\n mat-dialog-close\n >\n Cancel\n </button>\n </div>\n</ng-template>\n", dependencies: [{ kind: "component", type: i7.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], preserveWhitespaces: true });
|
|
748
|
-
}
|
|
749
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductTaxDeleteButtonComponent, decorators: [{
|
|
750
|
-
type: Component,
|
|
751
|
-
args: [{ selector: "app-product-tax-delete-button", template: "<mat-icon\n class=\"cursor-pointer text-secondary\"\n (click)=\"showDeleteDialog(deleteConfirmDialog)\"\n>\n delete\n</mat-icon>\n\n<ng-template #deleteConfirmDialog>\n <h3 mat-dialog-title>Delete Product Tax</h3>\n <div mat-dialog-content>\n Are you sure? You want to delete the product tax?\n </div>\n <div mat-dialog-actions class=\"d-flex justify-content-end gap-1 mb-2\">\n <button\n [disabled]=\"isDeleting\"\n type=\"button\"\n mat-raised-button\n color=\"warn\"\n (click)=\"delete()\"\n >\n Delete\n </button>\n <button\n [disabled]=\"isDeleting\"\n type=\"button\"\n mat-flat-button\n mat-dialog-close\n >\n Cancel\n </button>\n </div>\n</ng-template>\n" }]
|
|
752
|
-
}], ctorParameters: () => [{ type: i1.MatDialog }, { type: ProductTaxService }, { type: i1$1.AlertService }], propDecorators: { productTax: [{
|
|
753
|
-
type: Input
|
|
754
|
-
}], deleted: [{
|
|
755
|
-
type: Output
|
|
756
|
-
}] } });
|
|
757
|
-
|
|
758
|
-
class ProductTaxListComponent extends TechlifyListingControllerInterface {
|
|
759
|
-
product;
|
|
760
|
-
displayedColumns = ["#", "Tax", "Actions"];
|
|
761
|
-
ngOnInit() {
|
|
762
|
-
this.loadData();
|
|
763
|
-
}
|
|
764
|
-
loadData() {
|
|
765
|
-
this.models = this.product?.taxes ?? [];
|
|
766
|
-
}
|
|
767
|
-
onCreated(productTax) {
|
|
768
|
-
this.models.unshift(productTax);
|
|
769
|
-
this.models = [...this.models];
|
|
770
|
-
}
|
|
771
|
-
onDeleted(index) {
|
|
772
|
-
this.models.splice(index, 1);
|
|
773
|
-
this.models = [...this.models];
|
|
774
|
-
}
|
|
775
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductTaxListComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
776
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ProductTaxListComponent, selector: "app-product-tax-list", inputs: { product: "product" }, usesInheritance: true, ngImport: i0, template: "<mat-card>\n <mat-card-content\n class=\"pb-3 d-flex justify-content-between align-items-center gap-3\"\n >\n <div class=\"d-flex justify-content-start gap-2\">\n <span class=\"material-symbols-outlined\"> percent </span>\n <strong class=\"mb-0 text-dark\">Product Taxes</strong>\n </div>\n <app-product-tax-form-button\n [product]=\"product\"\n (saved)=\"onCreated($event)\"\n ></app-product-tax-form-button>\n </mat-card-content>\n <mat-divider></mat-divider>\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\">\n <ng-container matColumnDef=\"#\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"Tax\">\n <th mat-header-cell *matHeaderCellDef>Tax</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">\n {{ element?.tax?.title }} ({{ element?.tax?.code }})\n </p>\n <small class=\"text-secondary\"\n >{{ element?.tax?.value }} - {{ element?.tax?.type?.title }}</small\n >\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"Actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">\n <app-product-tax-delete-button\n [productTax]=\"element\"\n (deleted)=\"onDeleted(i)\"\n ></app-product-tax-delete-button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n </mat-card-content>\n</mat-card>\n", dependencies: [{ kind: "component", type: i6$1.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6$1.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6$1.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6$1.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i6$1.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6$1.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6$1.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6$1.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6$1.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6$1.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i3$2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3$2.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i6$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: ProductTaxFormButtonComponent, selector: "app-product-tax-form-button", inputs: ["product"], outputs: ["saved"] }, { kind: "component", type: ProductTaxDeleteButtonComponent, selector: "app-product-tax-delete-button", inputs: ["productTax"], outputs: ["deleted"] }], preserveWhitespaces: true });
|
|
777
|
-
}
|
|
778
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductTaxListComponent, decorators: [{
|
|
779
|
-
type: Component,
|
|
780
|
-
args: [{ selector: "app-product-tax-list", template: "<mat-card>\n <mat-card-content\n class=\"pb-3 d-flex justify-content-between align-items-center gap-3\"\n >\n <div class=\"d-flex justify-content-start gap-2\">\n <span class=\"material-symbols-outlined\"> percent </span>\n <strong class=\"mb-0 text-dark\">Product Taxes</strong>\n </div>\n <app-product-tax-form-button\n [product]=\"product\"\n (saved)=\"onCreated($event)\"\n ></app-product-tax-form-button>\n </mat-card-content>\n <mat-divider></mat-divider>\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\">\n <ng-container matColumnDef=\"#\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"Tax\">\n <th mat-header-cell *matHeaderCellDef>Tax</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">\n {{ element?.tax?.title }} ({{ element?.tax?.code }})\n </p>\n <small class=\"text-secondary\"\n >{{ element?.tax?.value }} - {{ element?.tax?.type?.title }}</small\n >\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"Actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">\n <app-product-tax-delete-button\n [productTax]=\"element\"\n (deleted)=\"onDeleted(i)\"\n ></app-product-tax-delete-button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n </mat-card-content>\n</mat-card>\n" }]
|
|
781
|
-
}], propDecorators: { product: [{
|
|
782
|
-
type: Input
|
|
783
|
-
}] } });
|
|
784
|
-
|
|
785
|
-
class ProductDeleteButtonComponent {
|
|
786
|
-
matDialog;
|
|
787
|
-
productService;
|
|
788
|
-
alertService;
|
|
789
|
-
product;
|
|
790
|
-
deleted = new EventEmitter();
|
|
791
|
-
isDeleting;
|
|
792
|
-
constructor(matDialog, productService, alertService) {
|
|
793
|
-
this.matDialog = matDialog;
|
|
794
|
-
this.productService = productService;
|
|
795
|
-
this.alertService = alertService;
|
|
796
|
-
}
|
|
797
|
-
/**
|
|
798
|
-
* Delete the product.
|
|
799
|
-
*/
|
|
800
|
-
deleteProduct() {
|
|
801
|
-
this.isDeleting = true;
|
|
802
|
-
this.productService.delete(this.product).subscribe({
|
|
803
|
-
next: () => {
|
|
804
|
-
this.deleted.emit();
|
|
805
|
-
this.isDeleting = false;
|
|
806
|
-
this.matDialog.closeAll();
|
|
807
|
-
this.alertService.addAlert("Product deleted successfully!", "success");
|
|
808
|
-
},
|
|
809
|
-
error: () => (this.isDeleting = false),
|
|
810
|
-
});
|
|
811
|
-
}
|
|
812
|
-
/**
|
|
813
|
-
* Show delete product dialog.
|
|
814
|
-
*
|
|
815
|
-
* @param templateRef
|
|
816
|
-
*/
|
|
817
|
-
showDeleteDialog(templateRef) {
|
|
818
|
-
this.matDialog.open(templateRef, { width: "500px" });
|
|
819
|
-
}
|
|
820
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductDeleteButtonComponent, deps: [{ token: i1.MatDialog }, { token: ProductService }, { token: i1$1.AlertService }], target: i0.ɵɵFactoryTarget.Component });
|
|
821
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ProductDeleteButtonComponent, selector: "app-product-delete-button", inputs: { product: "product" }, outputs: { deleted: "deleted" }, ngImport: i0, template: "<mat-icon\n class=\"cursor-pointer text-secondary\"\n (click)=\"showDeleteDialog(deleteProductDialog)\"\n>\n delete\n</mat-icon>\n\n<ng-template #deleteProductDialog>\n <h3 mat-dialog-title>Delete Product</h3>\n <div mat-dialog-content>\n Are you sure? You want to delete the\n <strong>{{ product?.name }}</strong> ?\n </div>\n <div mat-dialog-actions class=\"d-flex justify-content-end gap-1 mb-2\">\n <button\n [disabled]=\"isDeleting\"\n type=\"button\"\n mat-raised-button\n color=\"warn\"\n (click)=\"deleteProduct()\"\n >\n Delete\n </button>\n <button\n [disabled]=\"isDeleting\"\n type=\"button\"\n mat-flat-button\n mat-dialog-close\n >\n Cancel\n </button>\n </div>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "component", type: i7.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], preserveWhitespaces: true });
|
|
822
|
-
}
|
|
823
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductDeleteButtonComponent, decorators: [{
|
|
824
|
-
type: Component,
|
|
825
|
-
args: [{ selector: "app-product-delete-button", template: "<mat-icon\n class=\"cursor-pointer text-secondary\"\n (click)=\"showDeleteDialog(deleteProductDialog)\"\n>\n delete\n</mat-icon>\n\n<ng-template #deleteProductDialog>\n <h3 mat-dialog-title>Delete Product</h3>\n <div mat-dialog-content>\n Are you sure? You want to delete the\n <strong>{{ product?.name }}</strong> ?\n </div>\n <div mat-dialog-actions class=\"d-flex justify-content-end gap-1 mb-2\">\n <button\n [disabled]=\"isDeleting\"\n type=\"button\"\n mat-raised-button\n color=\"warn\"\n (click)=\"deleteProduct()\"\n >\n Delete\n </button>\n <button\n [disabled]=\"isDeleting\"\n type=\"button\"\n mat-flat-button\n mat-dialog-close\n >\n Cancel\n </button>\n </div>\n</ng-template>\n" }]
|
|
826
|
-
}], ctorParameters: () => [{ type: i1.MatDialog }, { type: ProductService }, { type: i1$1.AlertService }], propDecorators: { product: [{
|
|
827
|
-
type: Input
|
|
828
|
-
}], deleted: [{
|
|
829
|
-
type: Output
|
|
830
|
-
}] } });
|
|
831
|
-
|
|
832
|
-
class ProductBasicInfoComponent {
|
|
833
|
-
stockSummaryService;
|
|
834
|
-
product;
|
|
835
|
-
saved = new EventEmitter();
|
|
836
|
-
deleted = new EventEmitter();
|
|
837
|
-
stockSummary;
|
|
838
|
-
constructor(stockSummaryService) {
|
|
839
|
-
this.stockSummaryService = stockSummaryService;
|
|
840
|
-
}
|
|
841
|
-
ngOnInit() {
|
|
842
|
-
if (this.product) {
|
|
843
|
-
this.loadProductStocksSummary();
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
onProductSaved(product) {
|
|
847
|
-
this.product = product;
|
|
848
|
-
this.saved.emit(this.product);
|
|
849
|
-
}
|
|
850
|
-
/**
|
|
851
|
-
* Load product stocks summary.
|
|
852
|
-
*/
|
|
853
|
-
loadProductStocksSummary() {
|
|
854
|
-
const params = {
|
|
855
|
-
product_ids: this.product?.id,
|
|
856
|
-
include: "stock_receipts_quantity_sum,stock_issuances_quantity_sum,stock_quantity_remaining",
|
|
857
|
-
};
|
|
858
|
-
this.stockSummaryService.summary(params).subscribe({
|
|
859
|
-
next: (response) => {
|
|
860
|
-
this.stockSummary = response;
|
|
861
|
-
},
|
|
862
|
-
});
|
|
863
|
-
}
|
|
864
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductBasicInfoComponent, deps: [{ token: StockSummaryService }], target: i0.ɵɵFactoryTarget.Component });
|
|
865
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ProductBasicInfoComponent, selector: "app-product-basic-info", inputs: { product: "product" }, outputs: { saved: "saved", deleted: "deleted" }, ngImport: i0, template: "<mat-card *ngIf=\"product\" class=\"w-100\">\n <mat-card-content\n class=\"d-flex justify-content-between align-items-center mb-1 mb-2\"\n >\n <div class=\"d-flex justify-content-start gap-2\">\n <span class=\"material-symbols-outlined\"> campaign </span>\n <strong class=\"mb-0 text-dark\">Product Information</strong>\n </div>\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <app-product-form-button\n [product]=\"product\"\n (saved)=\"onProductSaved($event)\"\n ></app-product-form-button>\n <app-product-delete-button\n [product]=\"product\"\n (deleted)=\"deleted.emit()\"\n ></app-product-delete-button>\n </div>\n </mat-card-content>\n <mat-divider></mat-divider>\n <mat-card-content class=\"mt-3\">\n <h3 class=\"mb-1 font-weight-bold\">{{ product?.name }}</h3>\n <div class=\"d-flex flex-wrap gap-1\">\n <span\n class=\"badge badge-primary\"\n *ngFor=\"let category of product?.categories\"\n >\n {{ category?.title }}\n </span>\n </div>\n </mat-card-content>\n\n <mat-card-content\n class=\"mt-3 d-flex justify-content-between align-items-start\"\n >\n <div\n class=\"d-flex flex-column justify-content-start align-items-start gap-1\"\n >\n <small class=\"text-secondary\">SKU</small>\n <p class=\"mb-0\">{{ product?.sku }}</p>\n </div>\n <div\n class=\"d-flex flex-column justify-content-start align-items-start gap-1\"\n >\n <small class=\"text-secondary\">Measure</small>\n <p class=\"mb-0\">{{ product?.measure?.title }}</p>\n </div>\n <div\n class=\"d-flex flex-column justify-content-start align-items-start gap-1\"\n >\n <small class=\"text-secondary\">Reorder Point</small>\n <p class=\"mb-0\">{{ product?.reorder_point }}</p>\n </div>\n </mat-card-content>\n\n <mat-card-content\n class=\"mt-3 d-flex flex-column justify-content-start align-items-start gap-1\"\n >\n <small class=\"text-secondary\">Description</small>\n <p class=\"mb-0\">{{ product?.description }}</p>\n </mat-card-content>\n\n <mat-card-content\n class=\"mt-5 d-flex justify-content-between align-items-start\"\n >\n <div\n *ngIf=\"stockSummary\"\n class=\"d-flex flex-column justify-content-start align-items-start gap-1\"\n >\n <small class=\"text-secondary\">Stock Receipts</small>\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <span class=\"material-symbols-outlined\"> arrow_downward </span>\n <p class=\"mb-0\" style=\"font-size: 24px\">\n {{ stockSummary?.stock_receipts_quantity_sum }}\n </p>\n </div>\n <small *ngIf=\"product?.last_stock_receipt\" class=\"text-secondary\">\n Last Added On {{ product?.last_stock_receipt?.date | date }}\n </small>\n </div>\n <div\n *ngIf=\"stockSummary\"\n class=\"d-flex flex-column justify-content-start align-items-start gap-1\"\n >\n <small class=\"text-secondary\">Stock Issuances</small>\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <span class=\"material-symbols-outlined\"> ungroup </span>\n <p class=\"mb-0\" style=\"font-size: 24px\">\n {{ stockSummary?.stock_issuances_quantity_sum }}\n </p>\n </div>\n <small *ngIf=\"product?.last_stock_issuance\" class=\"text-secondary\">\n Last Added On {{ product?.last_stock_issuance?.date | date }}\n </small>\n </div>\n </mat-card-content>\n\n <mat-card-content\n *ngIf=\"stockSummary\"\n class=\"mt-3 d-flex justify-content-center align-items-center\"\n >\n <div\n class=\"d-flex flex-column justify-content-start align-items-start gap-1\"\n >\n <small class=\"text-secondary\">On Hand</small>\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <span class=\"material-symbols-outlined\"> inventory_2 </span>\n <p class=\"mb-0\" style=\"font-size: 24px\">\n {{ stockSummary?.stock_quantity_remaining }}\n </p>\n </div>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: [""], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3$2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3$2.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i6$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: ProductFormButtonComponent, selector: "app-product-form-button", inputs: ["product"], outputs: ["saved"] }, { kind: "component", type: ProductDeleteButtonComponent, selector: "app-product-delete-button", inputs: ["product"], outputs: ["deleted"] }, { kind: "pipe", type: i4.DatePipe, name: "date" }], preserveWhitespaces: true });
|
|
866
|
-
}
|
|
867
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductBasicInfoComponent, decorators: [{
|
|
868
|
-
type: Component,
|
|
869
|
-
args: [{ selector: "app-product-basic-info", template: "<mat-card *ngIf=\"product\" class=\"w-100\">\n <mat-card-content\n class=\"d-flex justify-content-between align-items-center mb-1 mb-2\"\n >\n <div class=\"d-flex justify-content-start gap-2\">\n <span class=\"material-symbols-outlined\"> campaign </span>\n <strong class=\"mb-0 text-dark\">Product Information</strong>\n </div>\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <app-product-form-button\n [product]=\"product\"\n (saved)=\"onProductSaved($event)\"\n ></app-product-form-button>\n <app-product-delete-button\n [product]=\"product\"\n (deleted)=\"deleted.emit()\"\n ></app-product-delete-button>\n </div>\n </mat-card-content>\n <mat-divider></mat-divider>\n <mat-card-content class=\"mt-3\">\n <h3 class=\"mb-1 font-weight-bold\">{{ product?.name }}</h3>\n <div class=\"d-flex flex-wrap gap-1\">\n <span\n class=\"badge badge-primary\"\n *ngFor=\"let category of product?.categories\"\n >\n {{ category?.title }}\n </span>\n </div>\n </mat-card-content>\n\n <mat-card-content\n class=\"mt-3 d-flex justify-content-between align-items-start\"\n >\n <div\n class=\"d-flex flex-column justify-content-start align-items-start gap-1\"\n >\n <small class=\"text-secondary\">SKU</small>\n <p class=\"mb-0\">{{ product?.sku }}</p>\n </div>\n <div\n class=\"d-flex flex-column justify-content-start align-items-start gap-1\"\n >\n <small class=\"text-secondary\">Measure</small>\n <p class=\"mb-0\">{{ product?.measure?.title }}</p>\n </div>\n <div\n class=\"d-flex flex-column justify-content-start align-items-start gap-1\"\n >\n <small class=\"text-secondary\">Reorder Point</small>\n <p class=\"mb-0\">{{ product?.reorder_point }}</p>\n </div>\n </mat-card-content>\n\n <mat-card-content\n class=\"mt-3 d-flex flex-column justify-content-start align-items-start gap-1\"\n >\n <small class=\"text-secondary\">Description</small>\n <p class=\"mb-0\">{{ product?.description }}</p>\n </mat-card-content>\n\n <mat-card-content\n class=\"mt-5 d-flex justify-content-between align-items-start\"\n >\n <div\n *ngIf=\"stockSummary\"\n class=\"d-flex flex-column justify-content-start align-items-start gap-1\"\n >\n <small class=\"text-secondary\">Stock Receipts</small>\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <span class=\"material-symbols-outlined\"> arrow_downward </span>\n <p class=\"mb-0\" style=\"font-size: 24px\">\n {{ stockSummary?.stock_receipts_quantity_sum }}\n </p>\n </div>\n <small *ngIf=\"product?.last_stock_receipt\" class=\"text-secondary\">\n Last Added On {{ product?.last_stock_receipt?.date | date }}\n </small>\n </div>\n <div\n *ngIf=\"stockSummary\"\n class=\"d-flex flex-column justify-content-start align-items-start gap-1\"\n >\n <small class=\"text-secondary\">Stock Issuances</small>\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <span class=\"material-symbols-outlined\"> ungroup </span>\n <p class=\"mb-0\" style=\"font-size: 24px\">\n {{ stockSummary?.stock_issuances_quantity_sum }}\n </p>\n </div>\n <small *ngIf=\"product?.last_stock_issuance\" class=\"text-secondary\">\n Last Added On {{ product?.last_stock_issuance?.date | date }}\n </small>\n </div>\n </mat-card-content>\n\n <mat-card-content\n *ngIf=\"stockSummary\"\n class=\"mt-3 d-flex justify-content-center align-items-center\"\n >\n <div\n class=\"d-flex flex-column justify-content-start align-items-start gap-1\"\n >\n <small class=\"text-secondary\">On Hand</small>\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <span class=\"material-symbols-outlined\"> inventory_2 </span>\n <p class=\"mb-0\" style=\"font-size: 24px\">\n {{ stockSummary?.stock_quantity_remaining }}\n </p>\n </div>\n </div>\n </mat-card-content>\n</mat-card>\n" }]
|
|
870
|
-
}], ctorParameters: () => [{ type: StockSummaryService }], propDecorators: { product: [{
|
|
871
|
-
type: Input
|
|
872
|
-
}], saved: [{
|
|
873
|
-
type: Output
|
|
874
|
-
}], deleted: [{
|
|
875
|
-
type: Output
|
|
876
|
-
}] } });
|
|
877
|
-
|
|
878
|
-
class ProductViewPageComponent {
|
|
879
|
-
productService;
|
|
880
|
-
activatedRoute;
|
|
881
|
-
location;
|
|
882
|
-
product;
|
|
883
|
-
id;
|
|
884
|
-
isLoading;
|
|
885
|
-
constructor(productService, activatedRoute, location) {
|
|
886
|
-
this.productService = productService;
|
|
887
|
-
this.activatedRoute = activatedRoute;
|
|
888
|
-
this.location = location;
|
|
889
|
-
this.id = this.activatedRoute.snapshot.params?.["id"];
|
|
890
|
-
}
|
|
891
|
-
ngOnInit() {
|
|
892
|
-
if (this.id) {
|
|
893
|
-
this.getProduct(this.id);
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
/**
|
|
897
|
-
* Get the product details.
|
|
898
|
-
*
|
|
899
|
-
* @param productId
|
|
900
|
-
*/
|
|
901
|
-
getProduct(productId) {
|
|
902
|
-
this.isLoading = true;
|
|
903
|
-
const params = {
|
|
904
|
-
with: "type,measure,incomeAccount,expenseAccount,categories,lastStockReceipt,lastStockIssuance,taxes.tax.type",
|
|
905
|
-
};
|
|
906
|
-
this.productService.show(productId, params).subscribe({
|
|
907
|
-
next: (result) => {
|
|
908
|
-
this.isLoading = false;
|
|
909
|
-
this.product = result?.item;
|
|
910
|
-
},
|
|
911
|
-
error: () => (this.isLoading = false),
|
|
912
|
-
});
|
|
913
|
-
}
|
|
914
|
-
/**
|
|
915
|
-
* Handle the on product update event.
|
|
916
|
-
*
|
|
917
|
-
* @param product
|
|
918
|
-
*/
|
|
919
|
-
onProductUpdated(product) {
|
|
920
|
-
this.getProduct(this.id);
|
|
921
|
-
}
|
|
922
|
-
/**
|
|
923
|
-
* Handle on product delete event.
|
|
924
|
-
*/
|
|
925
|
-
onProductDeleted() {
|
|
926
|
-
this.location.back();
|
|
927
|
-
}
|
|
928
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductViewPageComponent, deps: [{ token: ProductService }, { token: i2$1.ActivatedRoute }, { token: i4.Location }], target: i0.ɵɵFactoryTarget.Component });
|
|
929
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ProductViewPageComponent, selector: "app-product-view-page", ngImport: i0, template: "<mat-progress-bar mode=\"indeterminate\" *ngIf=\"isLoading\"></mat-progress-bar>\n\n<div\n *ngIf=\"product\"\n class=\"d-flex justify-content-start align-items-start gap-3\"\n>\n <div style=\"width: calc(25% - 1rem)\" class=\"d-flex flex-column gap-3\">\n <app-product-basic-info\n [product]=\"product\"\n #productBasicInfoComponent\n (deleted)=\"onProductDeleted()\"\n (saved)=\"onProductUpdated($event)\"\n ></app-product-basic-info>\n\n <app-product-tax-list [product]=\"product\"></app-product-tax-list>\n </div>\n <div style=\"width: calc(75%)\" class=\"d-flex flex-column gap-3\">\n <app-stock-receipts-list-page\n [product]=\"product\"\n (listUpdated)=\"\n getProduct(this.id);\n productBasicInfoComponent.loadProductStocksSummary()\n \"\n ></app-stock-receipts-list-page>\n\n <app-stock-issuances-list\n [product]=\"product\"\n (listUpdated)=\"\n getProduct(this.id);\n productBasicInfoComponent.loadProductStocksSummary()\n \"\n ></app-stock-issuances-list>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: StockReceiptsListPageComponent, selector: "app-stock-receipts-list-page", inputs: ["product"], outputs: ["listUpdated"] }, { kind: "component", type: StockIssuancesListComponent, selector: "app-stock-issuances-list", inputs: ["product", "issuableType", "issuableId", "label"], outputs: ["listUpdated"] }, { kind: "component", type: ProductTaxListComponent, selector: "app-product-tax-list", inputs: ["product"] }, { kind: "component", type: i7$2.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: ProductBasicInfoComponent, selector: "app-product-basic-info", inputs: ["product"], outputs: ["saved", "deleted"] }], preserveWhitespaces: true });
|
|
930
|
-
}
|
|
931
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductViewPageComponent, decorators: [{
|
|
932
|
-
type: Component,
|
|
933
|
-
args: [{ selector: "app-product-view-page", template: "<mat-progress-bar mode=\"indeterminate\" *ngIf=\"isLoading\"></mat-progress-bar>\n\n<div\n *ngIf=\"product\"\n class=\"d-flex justify-content-start align-items-start gap-3\"\n>\n <div style=\"width: calc(25% - 1rem)\" class=\"d-flex flex-column gap-3\">\n <app-product-basic-info\n [product]=\"product\"\n #productBasicInfoComponent\n (deleted)=\"onProductDeleted()\"\n (saved)=\"onProductUpdated($event)\"\n ></app-product-basic-info>\n\n <app-product-tax-list [product]=\"product\"></app-product-tax-list>\n </div>\n <div style=\"width: calc(75%)\" class=\"d-flex flex-column gap-3\">\n <app-stock-receipts-list-page\n [product]=\"product\"\n (listUpdated)=\"\n getProduct(this.id);\n productBasicInfoComponent.loadProductStocksSummary()\n \"\n ></app-stock-receipts-list-page>\n\n <app-stock-issuances-list\n [product]=\"product\"\n (listUpdated)=\"\n getProduct(this.id);\n productBasicInfoComponent.loadProductStocksSummary()\n \"\n ></app-stock-issuances-list>\n </div>\n</div>\n" }]
|
|
934
|
-
}], ctorParameters: () => [{ type: ProductService }, { type: i2$1.ActivatedRoute }, { type: i4.Location }] });
|
|
935
|
-
|
|
936
|
-
class ProductImportPageComponent {
|
|
937
|
-
importConfig = {
|
|
938
|
-
apiUrl: "api/products-import",
|
|
939
|
-
title: "Products",
|
|
940
|
-
importType: "product",
|
|
941
|
-
properties: [
|
|
942
|
-
{
|
|
943
|
-
label: "Name",
|
|
944
|
-
value: "name",
|
|
945
|
-
type: "text",
|
|
946
|
-
},
|
|
947
|
-
{
|
|
948
|
-
label: "SKU",
|
|
949
|
-
value: "sku",
|
|
950
|
-
type: "text",
|
|
951
|
-
},
|
|
952
|
-
{
|
|
953
|
-
label: "Initial Quantity",
|
|
954
|
-
value: "initial_quantity",
|
|
955
|
-
type: "number",
|
|
956
|
-
},
|
|
957
|
-
{
|
|
958
|
-
label: "Initial Quantity Date",
|
|
959
|
-
value: "initial_quantity_date",
|
|
960
|
-
type: "date",
|
|
961
|
-
},
|
|
962
|
-
{
|
|
963
|
-
label: "Reorder Point",
|
|
964
|
-
value: "reorder_point",
|
|
965
|
-
type: "number",
|
|
966
|
-
},
|
|
967
|
-
{
|
|
968
|
-
label: "Measure",
|
|
969
|
-
value: "measure",
|
|
970
|
-
type: "text",
|
|
971
|
-
},
|
|
972
|
-
{
|
|
973
|
-
label: "Categories",
|
|
974
|
-
value: "categories",
|
|
975
|
-
type: "text",
|
|
976
|
-
},
|
|
977
|
-
],
|
|
978
|
-
sampleFile: {
|
|
979
|
-
name: "Products Import",
|
|
980
|
-
path: "assets/product/product-import-sample.csv",
|
|
981
|
-
},
|
|
982
|
-
importHistory: {
|
|
983
|
-
isEnabled: true,
|
|
984
|
-
type: "product",
|
|
985
|
-
apiUrl: "api/import-histories",
|
|
986
|
-
},
|
|
987
|
-
viewRouterLink: "/inventory/products/",
|
|
988
|
-
};
|
|
989
|
-
constructor() { }
|
|
990
|
-
ngOnInit() { }
|
|
991
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductImportPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
992
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ProductImportPageComponent, selector: "app-product-import-page", ngImport: i0, template: "<app-import-csv [config]=\"importConfig\"></app-import-csv>\n", styles: [""], dependencies: [{ kind: "component", type: i1$1.ImportCsvComponent, selector: "app-import-csv", inputs: ["config"] }], preserveWhitespaces: true });
|
|
993
|
-
}
|
|
994
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductImportPageComponent, decorators: [{
|
|
995
|
-
type: Component,
|
|
996
|
-
args: [{ selector: "app-product-import-page", template: "<app-import-csv [config]=\"importConfig\"></app-import-csv>\n" }]
|
|
997
|
-
}], ctorParameters: () => [] });
|
|
998
|
-
|
|
999
|
-
const routes = [
|
|
1000
|
-
{
|
|
1001
|
-
path: "",
|
|
1002
|
-
component: ProductNavBarComponent,
|
|
1003
|
-
children: [
|
|
1004
|
-
{
|
|
1005
|
-
path: "",
|
|
1006
|
-
component: ProductListComponent,
|
|
1007
|
-
canLoad: [AuthenticationGuard],
|
|
1008
|
-
},
|
|
1009
|
-
{
|
|
1010
|
-
path: "import",
|
|
1011
|
-
component: ProductImportPageComponent,
|
|
1012
|
-
canLoad: [AuthenticationGuard],
|
|
1013
|
-
},
|
|
1014
|
-
{
|
|
1015
|
-
path: "measure",
|
|
1016
|
-
component: ProductMeasuresListComponent,
|
|
1017
|
-
canLoad: [AuthenticationGuard],
|
|
1018
|
-
},
|
|
1019
|
-
{
|
|
1020
|
-
path: ":id/view",
|
|
1021
|
-
component: ProductViewPageComponent,
|
|
1022
|
-
canLoad: [AuthenticationGuard],
|
|
1023
|
-
},
|
|
1024
|
-
{
|
|
1025
|
-
path: "**",
|
|
1026
|
-
redirectTo: "",
|
|
1027
|
-
pathMatch: "full",
|
|
1028
|
-
canLoad: [AuthenticationGuard],
|
|
1029
|
-
},
|
|
1030
|
-
],
|
|
1031
|
-
},
|
|
1032
|
-
];
|
|
1033
|
-
class ProductRoutingModule {
|
|
1034
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductRoutingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1035
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: ProductRoutingModule, imports: [i2$1.RouterModule], exports: [RouterModule] });
|
|
1036
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductRoutingModule, imports: [RouterModule.forChild(routes), RouterModule] });
|
|
1037
|
-
}
|
|
1038
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductRoutingModule, decorators: [{
|
|
1039
|
-
type: NgModule,
|
|
1040
|
-
args: [{
|
|
1041
|
-
imports: [RouterModule.forChild(routes)],
|
|
1042
|
-
exports: [RouterModule],
|
|
1043
|
-
}]
|
|
1044
|
-
}] });
|
|
1045
|
-
|
|
1046
|
-
class ProductTaxModule {
|
|
1047
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductTaxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1048
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: ProductTaxModule, declarations: [ProductTaxListComponent,
|
|
1049
|
-
ProductTaxFormButtonComponent,
|
|
1050
|
-
ProductTaxDeleteButtonComponent], imports: [CommonModule,
|
|
1051
|
-
MaterialModule,
|
|
1052
|
-
ReactiveFormsModule,
|
|
1053
|
-
SearchableSelectorModule], exports: [ProductTaxListComponent] });
|
|
1054
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductTaxModule, imports: [CommonModule,
|
|
1055
|
-
MaterialModule,
|
|
1056
|
-
ReactiveFormsModule,
|
|
1057
|
-
SearchableSelectorModule] });
|
|
1058
|
-
}
|
|
1059
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductTaxModule, decorators: [{
|
|
1060
|
-
type: NgModule,
|
|
1061
|
-
args: [{
|
|
1062
|
-
declarations: [
|
|
1063
|
-
ProductTaxListComponent,
|
|
1064
|
-
ProductTaxFormButtonComponent,
|
|
1065
|
-
ProductTaxDeleteButtonComponent,
|
|
1066
|
-
],
|
|
1067
|
-
imports: [
|
|
1068
|
-
CommonModule,
|
|
1069
|
-
MaterialModule,
|
|
1070
|
-
ReactiveFormsModule,
|
|
1071
|
-
SearchableSelectorModule,
|
|
1072
|
-
],
|
|
1073
|
-
exports: [ProductTaxListComponent],
|
|
1074
|
-
}]
|
|
1075
|
-
}] });
|
|
1076
|
-
|
|
1077
|
-
class ProductModule {
|
|
1078
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1079
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: ProductModule, declarations: [ProductListComponent,
|
|
1080
|
-
ProductFormComponent,
|
|
1081
|
-
ProductNavBarComponent,
|
|
1082
|
-
ProductMeasuresListComponent,
|
|
1083
|
-
ProductMeasureFormComponent,
|
|
1084
|
-
ProductViewPageComponent,
|
|
1085
|
-
ProductFormButtonComponent,
|
|
1086
|
-
ProductDeleteButtonComponent,
|
|
1087
|
-
ProductBasicInfoComponent,
|
|
1088
|
-
ProductImportPageComponent], imports: [CommonModule,
|
|
1089
|
-
ProductRoutingModule,
|
|
1090
|
-
SearchableSelectorModule,
|
|
1091
|
-
TimelineFilterModule,
|
|
1092
|
-
StockReceiptFormModule,
|
|
1093
|
-
StockIssueFormModule,
|
|
1094
|
-
ImportCsvModule,
|
|
1095
|
-
StockReceiptsModule,
|
|
1096
|
-
StockIssuancesListModule,
|
|
1097
|
-
ProductTaxModule,
|
|
1098
|
-
MaterialModule,
|
|
1099
|
-
MatProgressBarModule,
|
|
1100
|
-
InfiniteScrollModule,
|
|
1101
|
-
FlexModule,
|
|
1102
|
-
ReactiveFormsModule,
|
|
1103
|
-
FormsModule,
|
|
1104
|
-
ColumnSelectorModule], exports: [ProductFormComponent,
|
|
1105
|
-
ProductBasicInfoComponent,
|
|
1106
|
-
ProductFormButtonComponent] });
|
|
1107
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductModule, imports: [CommonModule,
|
|
1108
|
-
ProductRoutingModule,
|
|
1109
|
-
SearchableSelectorModule,
|
|
1110
|
-
TimelineFilterModule,
|
|
1111
|
-
StockReceiptFormModule,
|
|
1112
|
-
StockIssueFormModule,
|
|
1113
|
-
ImportCsvModule,
|
|
1114
|
-
StockReceiptsModule,
|
|
1115
|
-
StockIssuancesListModule,
|
|
1116
|
-
ProductTaxModule,
|
|
1117
|
-
MaterialModule,
|
|
1118
|
-
MatProgressBarModule,
|
|
1119
|
-
InfiniteScrollModule,
|
|
1120
|
-
FlexModule,
|
|
1121
|
-
ReactiveFormsModule,
|
|
1122
|
-
FormsModule,
|
|
1123
|
-
ColumnSelectorModule] });
|
|
1124
|
-
}
|
|
1125
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductModule, decorators: [{
|
|
1126
|
-
type: NgModule,
|
|
1127
|
-
args: [{
|
|
1128
|
-
declarations: [
|
|
1129
|
-
ProductListComponent,
|
|
1130
|
-
ProductFormComponent,
|
|
1131
|
-
ProductNavBarComponent,
|
|
1132
|
-
ProductMeasuresListComponent,
|
|
1133
|
-
ProductMeasureFormComponent,
|
|
1134
|
-
ProductViewPageComponent,
|
|
1135
|
-
ProductFormButtonComponent,
|
|
1136
|
-
ProductDeleteButtonComponent,
|
|
1137
|
-
ProductBasicInfoComponent,
|
|
1138
|
-
ProductImportPageComponent,
|
|
1139
|
-
],
|
|
1140
|
-
imports: [
|
|
1141
|
-
CommonModule,
|
|
1142
|
-
ProductRoutingModule,
|
|
1143
|
-
SearchableSelectorModule,
|
|
1144
|
-
TimelineFilterModule,
|
|
1145
|
-
StockReceiptFormModule,
|
|
1146
|
-
StockIssueFormModule,
|
|
1147
|
-
ImportCsvModule,
|
|
1148
|
-
StockReceiptsModule,
|
|
1149
|
-
StockIssuancesListModule,
|
|
1150
|
-
ProductTaxModule,
|
|
1151
|
-
MaterialModule,
|
|
1152
|
-
MatProgressBarModule,
|
|
1153
|
-
InfiniteScrollModule,
|
|
1154
|
-
FlexModule,
|
|
1155
|
-
ReactiveFormsModule,
|
|
1156
|
-
FormsModule,
|
|
1157
|
-
ColumnSelectorModule,
|
|
1158
|
-
],
|
|
1159
|
-
exports: [
|
|
1160
|
-
ProductFormComponent,
|
|
1161
|
-
ProductBasicInfoComponent,
|
|
1162
|
-
ProductFormButtonComponent,
|
|
1163
|
-
],
|
|
1164
|
-
}]
|
|
1165
|
-
}] });
|
|
1166
|
-
|
|
1167
|
-
export { ProductModule };
|
|
1168
|
-
//# sourceMappingURL=techlify-inventory-common-product.module-BV9Cy88x.mjs.map
|