@hitsoft/kadooglu.kalite 0.0.0-stage → 1.0.1
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/README.md +23 -2
- package/config/enums/index.d.ts +1 -0
- package/config/enums/route-names.d.ts +5 -0
- package/config/index.d.ts +5 -0
- package/config/kalite-config.module.d.ts +8 -0
- package/config/providers/index.d.ts +1 -0
- package/config/providers/route.provider.d.ts +4 -0
- package/config/public-api.d.ts +3 -0
- package/esm2020/config/enums/index.mjs +2 -0
- package/esm2020/config/enums/route-names.mjs +2 -0
- package/esm2020/config/hitsoft-kadooglu.kalite-config.mjs +5 -0
- package/esm2020/config/kalite-config.module.mjs +18 -0
- package/esm2020/config/providers/index.mjs +2 -0
- package/esm2020/config/providers/route.provider.mjs +57 -0
- package/esm2020/config/public-api.mjs +4 -0
- package/esm2020/hitsoft-kadooglu.kalite.mjs +5 -0
- package/esm2020/lib/components/intake-form.component.mjs +162 -0
- package/esm2020/lib/components/intake-list.component.mjs +80 -0
- package/esm2020/lib/components/kalite.component.mjs +18 -0
- package/esm2020/lib/components/process-analysis.component.mjs +197 -0
- package/esm2020/lib/components/quality-definitions.component.mjs +97 -0
- package/esm2020/lib/components/quality-notifications.component.mjs +64 -0
- package/esm2020/lib/components/quality-parameters.component.mjs +332 -0
- package/esm2020/lib/components/quality-reports.component.mjs +107 -0
- package/esm2020/lib/kalite-notification.module.mjs +23 -0
- package/esm2020/lib/kalite-routing.module.mjs +41 -0
- package/esm2020/lib/kalite.module.mjs +41 -0
- package/esm2020/lib/models/intake.models.mjs +2 -0
- package/esm2020/lib/models/quality.models.mjs +2 -0
- package/esm2020/lib/services/kalite.service.mjs +21 -0
- package/esm2020/lib/services/print-form.mjs +96 -0
- package/esm2020/lib/services/quality-api.service.mjs +119 -0
- package/esm2020/lib/services/quality-measurements.mjs +127 -0
- package/esm2020/public-api.mjs +16 -0
- package/fesm2015/hitsoft-kadooglu.kalite-config.mjs +80 -0
- package/fesm2015/hitsoft-kadooglu.kalite-config.mjs.map +1 -0
- package/fesm2015/hitsoft-kadooglu.kalite.mjs +1483 -0
- package/fesm2015/hitsoft-kadooglu.kalite.mjs.map +1 -0
- package/fesm2020/hitsoft-kadooglu.kalite-config.mjs +80 -0
- package/fesm2020/hitsoft-kadooglu.kalite-config.mjs.map +1 -0
- package/fesm2020/hitsoft-kadooglu.kalite.mjs +1442 -0
- package/fesm2020/hitsoft-kadooglu.kalite.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/components/intake-form.component.d.ts +50 -0
- package/lib/components/intake-list.component.d.ts +48 -0
- package/lib/components/kalite.component.d.ts +10 -0
- package/lib/components/process-analysis.component.d.ts +46 -0
- package/lib/components/quality-definitions.component.d.ts +46 -0
- package/lib/components/quality-notifications.component.d.ts +44 -0
- package/lib/components/quality-parameters.component.d.ts +82 -0
- package/lib/components/quality-reports.component.d.ts +31 -0
- package/lib/kalite-notification.module.d.ts +14 -0
- package/lib/kalite-routing.module.d.ts +7 -0
- package/lib/kalite.module.d.ts +23 -0
- package/lib/models/intake.models.d.ts +185 -0
- package/lib/models/quality.models.d.ts +114 -0
- package/lib/services/kalite.service.d.ts +10 -0
- package/lib/services/print-form.d.ts +2 -0
- package/lib/services/quality-api.service.d.ts +71 -0
- package/lib/services/quality-measurements.d.ts +8 -0
- package/package.json +42 -3
- package/public-api.d.ts +12 -0
|
@@ -0,0 +1,1483 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Injectable, Component, ViewChild, NgModule, APP_INITIALIZER } from '@angular/core';
|
|
3
|
+
import * as i2 from '@abp/ng.core';
|
|
4
|
+
import { CoreModule, LazyModuleFactory } from '@abp/ng.core';
|
|
5
|
+
import * as i3 from '@angular/common';
|
|
6
|
+
import * as i5 from '@angular/forms';
|
|
7
|
+
import { FormsModule } from '@angular/forms';
|
|
8
|
+
import { defer, firstValueFrom, Subject, timer, of } from 'rxjs';
|
|
9
|
+
import { finalize, takeUntil, switchMap, catchError } from 'rxjs/operators';
|
|
10
|
+
import * as i2$1 from '@angular/router';
|
|
11
|
+
import { RouterModule } from '@angular/router';
|
|
12
|
+
import * as i6 from '@abp/ng.theme.shared';
|
|
13
|
+
import { NavItemsService, ThemeSharedModule } from '@abp/ng.theme.shared';
|
|
14
|
+
import { __awaiter } from 'tslib';
|
|
15
|
+
import CustomStore from 'devextreme/data/custom_store';
|
|
16
|
+
import * as i7 from 'devextreme-angular';
|
|
17
|
+
import { DxDataGridModule } from 'devextreme-angular';
|
|
18
|
+
import * as i8 from 'devextreme-angular/ui/nested';
|
|
19
|
+
import * as i9 from 'devextreme-angular/core';
|
|
20
|
+
import * as i10 from '@ng-bootstrap/ng-bootstrap';
|
|
21
|
+
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
|
|
22
|
+
|
|
23
|
+
class KaliteService {
|
|
24
|
+
constructor(restService) {
|
|
25
|
+
this.restService = restService;
|
|
26
|
+
this.apiName = 'Kalite';
|
|
27
|
+
}
|
|
28
|
+
sample() {
|
|
29
|
+
return this.restService.request({ method: 'GET', url: '/api/Kalite/sample' }, { apiName: this.apiName });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
KaliteService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KaliteService, deps: [{ token: i2.RestService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
33
|
+
KaliteService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KaliteService, providedIn: 'root' });
|
|
34
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KaliteService, decorators: [{
|
|
35
|
+
type: Injectable,
|
|
36
|
+
args: [{
|
|
37
|
+
providedIn: 'root',
|
|
38
|
+
}]
|
|
39
|
+
}], ctorParameters: function () { return [{ type: i2.RestService }]; } });
|
|
40
|
+
|
|
41
|
+
class KaliteComponent {
|
|
42
|
+
constructor(service) {
|
|
43
|
+
this.service = service;
|
|
44
|
+
}
|
|
45
|
+
ngOnInit() {
|
|
46
|
+
this.service.sample().subscribe(console.log);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
KaliteComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KaliteComponent, deps: [{ token: KaliteService }], target: i0.ɵɵFactoryTarget.Component });
|
|
50
|
+
KaliteComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: KaliteComponent, selector: "lib-kalite", ngImport: i0, template: ` <p>kalite works!</p> `, isInline: true });
|
|
51
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KaliteComponent, decorators: [{
|
|
52
|
+
type: Component,
|
|
53
|
+
args: [{ selector: 'lib-kalite', template: ` <p>kalite works!</p> ` }]
|
|
54
|
+
}], ctorParameters: function () { return [{ type: KaliteService }]; } });
|
|
55
|
+
|
|
56
|
+
function applicableLimit(limits, code, date, oilType = '', origin = '') {
|
|
57
|
+
return limits.filter(l => l.active && l.parameterCode === code && (!l.oilType || l.oilType === oilType) &&
|
|
58
|
+
(!l.origin || l.origin === origin) && (!l.validFrom || l.validFrom.slice(0, 10) <= date) &&
|
|
59
|
+
(!l.validUntil || l.validUntil.slice(0, 10) >= date))
|
|
60
|
+
.sort((a, b) => Number(!!b.oilType) + Number(!!b.origin) - Number(!!a.oilType) - Number(!!a.origin) ||
|
|
61
|
+
(b.validFrom || '').localeCompare(a.validFrom || ''))[0];
|
|
62
|
+
}
|
|
63
|
+
// A small arithmetic parser; formulas are never executed as JavaScript.
|
|
64
|
+
function evaluateFormula(formula, resolve) {
|
|
65
|
+
let pos = 0;
|
|
66
|
+
const space = () => {
|
|
67
|
+
while (/\s/.test(formula[pos] || '') && pos < formula.length)
|
|
68
|
+
pos++;
|
|
69
|
+
};
|
|
70
|
+
const take = (ch) => {
|
|
71
|
+
space();
|
|
72
|
+
if (formula[pos] !== ch)
|
|
73
|
+
return false;
|
|
74
|
+
pos++;
|
|
75
|
+
return true;
|
|
76
|
+
};
|
|
77
|
+
const binary = (a, b, op) => {
|
|
78
|
+
if (a == null || b == null)
|
|
79
|
+
return null;
|
|
80
|
+
if (op === '/' && b === 0)
|
|
81
|
+
throw new Error('Formülde sıfıra bölme var.');
|
|
82
|
+
return op === '+' ? a + b : op === '-' ? a - b : op === '*' ? a * b : a / b;
|
|
83
|
+
};
|
|
84
|
+
const factor = () => {
|
|
85
|
+
var _a;
|
|
86
|
+
space();
|
|
87
|
+
if (take('-')) {
|
|
88
|
+
const value = factor();
|
|
89
|
+
return value == null ? null : -value;
|
|
90
|
+
}
|
|
91
|
+
if (take('(')) {
|
|
92
|
+
const value = expression();
|
|
93
|
+
if (!take(')'))
|
|
94
|
+
throw new Error('Formül parantezi kapanmamış.');
|
|
95
|
+
return value;
|
|
96
|
+
}
|
|
97
|
+
if (take('[')) {
|
|
98
|
+
const end = formula.indexOf(']', pos);
|
|
99
|
+
if (end < 0)
|
|
100
|
+
throw new Error('Parametre kodu kapanmamış.');
|
|
101
|
+
const key = formula.slice(pos, end);
|
|
102
|
+
pos = end + 1;
|
|
103
|
+
return resolve(key);
|
|
104
|
+
}
|
|
105
|
+
const token = (_a = formula.slice(pos).match(/^[\p{L}\p{N}_.]+/u)) === null || _a === void 0 ? void 0 : _a[0];
|
|
106
|
+
if (!token)
|
|
107
|
+
throw new Error('Geçersiz hesaplama formülü.');
|
|
108
|
+
pos += token.length;
|
|
109
|
+
return /^\d+(\.\d+)?$/.test(token) ? Number(token) : resolve(token);
|
|
110
|
+
};
|
|
111
|
+
const term = () => {
|
|
112
|
+
let value = factor();
|
|
113
|
+
while (true) {
|
|
114
|
+
if (take('*'))
|
|
115
|
+
value = binary(value, factor(), '*');
|
|
116
|
+
else if (take('/'))
|
|
117
|
+
value = binary(value, factor(), '/');
|
|
118
|
+
else
|
|
119
|
+
return value;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
const expression = () => {
|
|
123
|
+
let value = term();
|
|
124
|
+
while (true) {
|
|
125
|
+
if (take('+'))
|
|
126
|
+
value = binary(value, term(), '+');
|
|
127
|
+
else if (take('-'))
|
|
128
|
+
value = binary(value, term(), '-');
|
|
129
|
+
else
|
|
130
|
+
return value;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const value = expression();
|
|
134
|
+
space();
|
|
135
|
+
if (pos !== formula.length || (value != null && !Number.isFinite(value)))
|
|
136
|
+
throw new Error('Geçersiz hesaplama sonucu.');
|
|
137
|
+
return value;
|
|
138
|
+
}
|
|
139
|
+
function recalculate(parameters, values, limits, date, oilType = '', origin = '') {
|
|
140
|
+
const visiting = new Set();
|
|
141
|
+
const resolved = new Map();
|
|
142
|
+
const valueFor = (p) => {
|
|
143
|
+
let value = values.find(x => x.parameterCode === p.code);
|
|
144
|
+
if (!value) {
|
|
145
|
+
value = { parameterCode: p.code, number: null, text: '' };
|
|
146
|
+
values.push(value);
|
|
147
|
+
}
|
|
148
|
+
return value;
|
|
149
|
+
};
|
|
150
|
+
const resolve = (code) => {
|
|
151
|
+
if (resolved.has(code))
|
|
152
|
+
return resolved.get(code);
|
|
153
|
+
const p = parameters.find(x => x.code === code);
|
|
154
|
+
if (!p)
|
|
155
|
+
throw new Error(`Formülde tanımsız parametre: ${code}`);
|
|
156
|
+
if (visiting.has(code))
|
|
157
|
+
throw new Error('Hesaplama formülünde döngü var.');
|
|
158
|
+
visiting.add(code);
|
|
159
|
+
const number = p.calculated ? evaluateFormula(p.formula, resolve) : valueFor(p).number;
|
|
160
|
+
const result = p.calculated && number != null ? Number(number.toFixed(p.decimalPlaces)) : number;
|
|
161
|
+
if (p.calculated)
|
|
162
|
+
valueFor(p).number = result;
|
|
163
|
+
visiting.delete(code);
|
|
164
|
+
resolved.set(code, result);
|
|
165
|
+
return result;
|
|
166
|
+
};
|
|
167
|
+
for (const p of parameters) {
|
|
168
|
+
resolve(p.code);
|
|
169
|
+
const v = valueFor(p);
|
|
170
|
+
const l = applicableLimit(limits, p.code, date, oilType, origin);
|
|
171
|
+
v.appliedMinimum = l === null || l === void 0 ? void 0 : l.minimum;
|
|
172
|
+
v.appliedMaximum = l === null || l === void 0 ? void 0 : l.maximum;
|
|
173
|
+
v.appliedNominal = l === null || l === void 0 ? void 0 : l.nominal;
|
|
174
|
+
v.appliedExpectedText = l === null || l === void 0 ? void 0 : l.expectedText;
|
|
175
|
+
v.outOfLimit = !!l && ((v.number != null && ((l.minimum != null && v.number < l.minimum) ||
|
|
176
|
+
(l.maximum != null && v.number > l.maximum))) || (!!v.text && !!l.expectedText && v.text.trim().toLocaleLowerCase('tr-TR') !== l.expectedText.trim().toLocaleLowerCase('tr-TR')));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function download(blob, name) {
|
|
180
|
+
const url = URL.createObjectURL(blob);
|
|
181
|
+
const link = document.createElement('a');
|
|
182
|
+
link.href = url;
|
|
183
|
+
link.download = name;
|
|
184
|
+
link.click();
|
|
185
|
+
setTimeout(() => URL.revokeObjectURL(url), 1000);
|
|
186
|
+
}
|
|
187
|
+
function localDate(date = new Date()) { return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; }
|
|
188
|
+
function errorMessage(error) { var _a, _b, _c; return ((_b = (_a = error === null || error === void 0 ? void 0 : error.error) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.message) || ((_c = error === null || error === void 0 ? void 0 : error.error) === null || _c === void 0 ? void 0 : _c.message) || 'İşlem tamamlanamadı. Bağlantıyı ve alanları kontrol edin.'; }
|
|
189
|
+
function statusLabel(status) { return { Waiting: 'Kalite Kontrol Bekliyor', Draft: 'Taslak', Accepted: 'Kalite Kontrol Kabul', Rejected: 'Kalite Kontrol Ret', Approved: 'Onaylı', LaborantSigned: 'Laborant İmzalı', Checked: 'Kontrol Edildi' }[status] || status || '—'; }
|
|
190
|
+
|
|
191
|
+
class QualityApiService {
|
|
192
|
+
constructor(rest) {
|
|
193
|
+
this.rest = rest;
|
|
194
|
+
this.apiName = 'Kalite';
|
|
195
|
+
}
|
|
196
|
+
movementTypes() { return this.get('/api/kalite/definitions/movement-types'); }
|
|
197
|
+
qualityMovementTypes() { return this.get('/api/kalite/definitions/quality-movement-types'); }
|
|
198
|
+
reportForms() { return this.get('/api/kalite/definitions/forms'); }
|
|
199
|
+
definitionFacilities() { return this.get('/api/kalite/definitions/facilities'); }
|
|
200
|
+
movementDetails() { return this.get('/api/kalite/definitions/movement-details'); }
|
|
201
|
+
tanks() { return this.get('/api/kalite/definitions/tanks'); }
|
|
202
|
+
shifts() { return this.get('/api/kalite/definitions/shifts'); }
|
|
203
|
+
laborants() { return this.get('/api/kalite/definitions/laborants'); }
|
|
204
|
+
saveDetail(input, createOnly = false) { return this.put('/api/kalite/definitions/movement-detail?createOnly=' + createOnly, input); }
|
|
205
|
+
deleteDetail(code) { return this.delete(`/api/kalite/definitions/movement-detail/${encodeURIComponent(code)}`); }
|
|
206
|
+
saveTank(input, createOnly = false) { return this.put('/api/kalite/definitions/tank?createOnly=' + createOnly, input); }
|
|
207
|
+
deleteTank(code) { return this.delete(`/api/kalite/definitions/tank/${encodeURIComponent(code)}`); }
|
|
208
|
+
saveShift(input) { return this.put('/api/kalite/definitions/shift', input); }
|
|
209
|
+
deleteShift(code) { return this.delete(`/api/kalite/definitions/shift/${encodeURIComponent(code)}`); }
|
|
210
|
+
intakeList(query) { return this.get('/api/kalite/intake?' + this.query(query)); }
|
|
211
|
+
intake(id, detailCode, batchNumber) {
|
|
212
|
+
return this.get(`/api/kalite/intake/${id}?` + this.query({ detailCode, batchNumber }));
|
|
213
|
+
}
|
|
214
|
+
intakeTemplate(code) { return this.get(`/api/kalite/intake/template/${encodeURIComponent(code)}`); }
|
|
215
|
+
saveIntake(input) { return this.put('/api/kalite/intake', input); }
|
|
216
|
+
saveComposite(input) { return this.put('/api/kalite/intake/composite', input); }
|
|
217
|
+
cancelIntake(id, revision, reason) { return this.post(`/api/kalite/intake/${id}/cancel`, { revision, reason }); }
|
|
218
|
+
intakePdf(id) { return this.blob(`/api/kalite/intake/${id}/pdf`); }
|
|
219
|
+
report(filter, exportData = false) {
|
|
220
|
+
return this.get('/api/kalite/reports' + (exportData ? '/export' : '') + '?' + this.query(filter));
|
|
221
|
+
}
|
|
222
|
+
reportPdf(filter) { return this.blob('/api/kalite/reports/pdf?' + this.query(filter)); }
|
|
223
|
+
notifications() { return this.get('/api/kalite/notifications'); }
|
|
224
|
+
unreadNotifications() { return this.get('/api/kalite/notifications/unread-count'); }
|
|
225
|
+
readNotification(code) { return this.post(`/api/kalite/notifications/${encodeURIComponent(code)}/read`, {}); }
|
|
226
|
+
notificationSettings() { return this.get('/api/kalite/notifications/settings'); }
|
|
227
|
+
notificationFailures() { return this.get('/api/kalite/notifications/failures'); }
|
|
228
|
+
saveNotificationSettings(input) { return this.put('/api/kalite/notifications/settings', input); }
|
|
229
|
+
query(values) {
|
|
230
|
+
return Object.entries(values).filter(([, value]) => value != null && value !== '')
|
|
231
|
+
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`).join('&');
|
|
232
|
+
}
|
|
233
|
+
blob(url) {
|
|
234
|
+
return this.rest.request({ method: 'GET', url, responseType: 'blob' }, { apiName: this.apiName });
|
|
235
|
+
}
|
|
236
|
+
forms() {
|
|
237
|
+
return this.get('/api/kalite/parameters/forms');
|
|
238
|
+
}
|
|
239
|
+
template(code) {
|
|
240
|
+
return this.get(`/api/kalite/parameters/template/${encodeURIComponent(code)}`);
|
|
241
|
+
}
|
|
242
|
+
parameterFacilities() {
|
|
243
|
+
return this.get('/api/kalite/parameters/facilities');
|
|
244
|
+
}
|
|
245
|
+
steps(facilityCode) {
|
|
246
|
+
return this.get(`/api/kalite/parameters/steps/${encodeURIComponent(facilityCode)}`);
|
|
247
|
+
}
|
|
248
|
+
saveStep(step) {
|
|
249
|
+
return this.put('/api/kalite/parameters/step', step);
|
|
250
|
+
}
|
|
251
|
+
saveForm(form) {
|
|
252
|
+
return this.put('/api/kalite/parameters/form', form);
|
|
253
|
+
}
|
|
254
|
+
createParameter(parameter) {
|
|
255
|
+
return this.post('/api/kalite/parameters/parameter', parameter);
|
|
256
|
+
}
|
|
257
|
+
updateParameter(parameter) {
|
|
258
|
+
return this.put('/api/kalite/parameters/parameter', parameter);
|
|
259
|
+
}
|
|
260
|
+
deleteParameter(code) {
|
|
261
|
+
return this.delete(`/api/kalite/parameters/parameter/${encodeURIComponent(code)}`);
|
|
262
|
+
}
|
|
263
|
+
createLimit(limit) {
|
|
264
|
+
return this.post('/api/kalite/parameters/limit', limit);
|
|
265
|
+
}
|
|
266
|
+
updateLimit(limit) {
|
|
267
|
+
return this.put('/api/kalite/parameters/limit', limit);
|
|
268
|
+
}
|
|
269
|
+
deleteLimit(code) {
|
|
270
|
+
return this.delete(`/api/kalite/parameters/limit/${encodeURIComponent(code)}`);
|
|
271
|
+
}
|
|
272
|
+
facilities() {
|
|
273
|
+
return this.get('/api/kalite/process/facilities');
|
|
274
|
+
}
|
|
275
|
+
process(facilityCode, businessDate) {
|
|
276
|
+
return this.get(`/api/kalite/process?facilityCode=${encodeURIComponent(facilityCode)}&businessDate=${encodeURIComponent(businessDate)}`);
|
|
277
|
+
}
|
|
278
|
+
saveProcess(input) {
|
|
279
|
+
return this.put('/api/kalite/process', input);
|
|
280
|
+
}
|
|
281
|
+
decision(code, action, revision, reason) {
|
|
282
|
+
return this.post(`/api/kalite/process/${encodeURIComponent(code)}/${action}`, { revision, reason });
|
|
283
|
+
}
|
|
284
|
+
pdf(code) {
|
|
285
|
+
return this.rest.request({ method: 'GET', url: `/api/kalite/process/${encodeURIComponent(code)}/pdf`, responseType: 'blob' }, { apiName: this.apiName });
|
|
286
|
+
}
|
|
287
|
+
get(url) {
|
|
288
|
+
return this.rest.request({ method: 'GET', url }, { apiName: this.apiName });
|
|
289
|
+
}
|
|
290
|
+
post(url, body) {
|
|
291
|
+
return this.rest.request({ method: 'POST', url, body }, { apiName: this.apiName });
|
|
292
|
+
}
|
|
293
|
+
put(url, body) {
|
|
294
|
+
return this.rest.request({ method: 'PUT', url, body }, { apiName: this.apiName });
|
|
295
|
+
}
|
|
296
|
+
delete(url) {
|
|
297
|
+
return this.rest.request({ method: 'DELETE', url }, { apiName: this.apiName });
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
QualityApiService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: QualityApiService, deps: [{ token: i2.RestService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
301
|
+
QualityApiService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: QualityApiService, providedIn: 'root' });
|
|
302
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: QualityApiService, decorators: [{
|
|
303
|
+
type: Injectable,
|
|
304
|
+
args: [{ providedIn: 'root' }]
|
|
305
|
+
}], ctorParameters: function () { return [{ type: i2.RestService }]; } });
|
|
306
|
+
|
|
307
|
+
class ProcessAnalysisComponent {
|
|
308
|
+
constructor(api, permissions) {
|
|
309
|
+
this.api = api;
|
|
310
|
+
this.permissions = permissions;
|
|
311
|
+
this.tanks = [];
|
|
312
|
+
this.facilities = [];
|
|
313
|
+
this.facilityCode = '';
|
|
314
|
+
this.businessDate = this.today();
|
|
315
|
+
this.analysis = null;
|
|
316
|
+
this.groups = [];
|
|
317
|
+
this.parameters = [];
|
|
318
|
+
this.reason = '';
|
|
319
|
+
this.busy = true;
|
|
320
|
+
this.busyText = 'Tesisler yükleniyor…';
|
|
321
|
+
this.error = '';
|
|
322
|
+
this.reasonError = '';
|
|
323
|
+
}
|
|
324
|
+
ngOnInit() {
|
|
325
|
+
this.api.tanks().subscribe({ next: x => this.tanks = x.filter(t => t.active), error: () => { } });
|
|
326
|
+
this.api.facilities().subscribe({
|
|
327
|
+
next: facilities => {
|
|
328
|
+
var _a;
|
|
329
|
+
this.facilities = facilities;
|
|
330
|
+
this.facilityCode = ((_a = facilities[0]) === null || _a === void 0 ? void 0 : _a.code) || '';
|
|
331
|
+
if (this.facilityCode)
|
|
332
|
+
this.load();
|
|
333
|
+
else
|
|
334
|
+
this.busy = false;
|
|
335
|
+
},
|
|
336
|
+
error: () => { this.error = 'Tesisler yüklenemedi.'; this.busy = false; },
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
get editable() {
|
|
340
|
+
var _a;
|
|
341
|
+
return !this.busy && ((_a = this.analysis) === null || _a === void 0 ? void 0 : _a.status) === 'Draft' &&
|
|
342
|
+
this.permissions.getGrantedPolicy('Kalite.ProcessAnalysis.Create');
|
|
343
|
+
}
|
|
344
|
+
get hasOutOfLimit() {
|
|
345
|
+
var _a;
|
|
346
|
+
return ((_a = this.analysis) === null || _a === void 0 ? void 0 : _a.hours.some(h => h.measurements.some(v => v.outOfLimit))) || false;
|
|
347
|
+
}
|
|
348
|
+
get statusText() {
|
|
349
|
+
var _a;
|
|
350
|
+
return { Draft: 'Taslak', LaborantSigned: 'Laborant imzaladı',
|
|
351
|
+
Checked: 'Mühendis kontrol etti', Approved: 'Onaylı' }[((_a = this.analysis) === null || _a === void 0 ? void 0 : _a.status) || ''] || '';
|
|
352
|
+
}
|
|
353
|
+
allowed(permission) {
|
|
354
|
+
return this.permissions.getGrantedPolicy(`Kalite.ProcessAnalysis.${permission}`);
|
|
355
|
+
}
|
|
356
|
+
load() {
|
|
357
|
+
if (!this.facilityCode || !this.businessDate)
|
|
358
|
+
return;
|
|
359
|
+
this.busy = true;
|
|
360
|
+
this.busyText = 'Analiz verileri yükleniyor…';
|
|
361
|
+
this.error = '';
|
|
362
|
+
this.api.process(this.facilityCode, this.businessDate).subscribe({
|
|
363
|
+
next: analysis => {
|
|
364
|
+
this.applyAnalysis(analysis);
|
|
365
|
+
this.busy = false;
|
|
366
|
+
},
|
|
367
|
+
error: () => { this.error = 'Analiz formu yüklenemedi.'; this.busy = false; },
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
applyAnalysis(analysis) {
|
|
371
|
+
this.analysis = analysis;
|
|
372
|
+
const template = analysis.templateSnapshot;
|
|
373
|
+
this.groups = [...template.steps].sort((a, b) => a.order - b.order).map(step => ({
|
|
374
|
+
step,
|
|
375
|
+
parameters: template.parameters.filter(p => p.active && p.stepCode === step.processCode)
|
|
376
|
+
.sort((a, b) => a.order - b.order),
|
|
377
|
+
}));
|
|
378
|
+
this.parameters = [].concat(...this.groups.map(group => group.parameters));
|
|
379
|
+
for (const hour of analysis.hours) {
|
|
380
|
+
hour.measurements || (hour.measurements = []);
|
|
381
|
+
for (const parameter of this.parameters) {
|
|
382
|
+
if (!hour.measurements.some(v => v.parameterCode === parameter.code)) {
|
|
383
|
+
hour.measurements.push({ parameterCode: parameter.code, number: null, text: '', outOfLimit: false });
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
measurement(row, parameter) {
|
|
389
|
+
return row.measurements.find(v => v.parameterCode === parameter.code);
|
|
390
|
+
}
|
|
391
|
+
limit(parameter) {
|
|
392
|
+
var _a, _b;
|
|
393
|
+
return applicableLimit(((_a = this.analysis) === null || _a === void 0 ? void 0 : _a.templateSnapshot.limits) || [], parameter.code, this.businessDate, ((_b = this.analysis) === null || _b === void 0 ? void 0 : _b.oilType) || '');
|
|
394
|
+
}
|
|
395
|
+
limitLabel(parameter) {
|
|
396
|
+
const limit = this.limit(parameter);
|
|
397
|
+
if (!limit)
|
|
398
|
+
return '—';
|
|
399
|
+
if (limit.expectedText)
|
|
400
|
+
return limit.expectedText;
|
|
401
|
+
if (limit.minimum != null && limit.maximum != null)
|
|
402
|
+
return `${limit.minimum}–${limit.maximum}`;
|
|
403
|
+
if (limit.minimum != null)
|
|
404
|
+
return `≥ ${limit.minimum}`;
|
|
405
|
+
if (limit.maximum != null)
|
|
406
|
+
return `≤ ${limit.maximum}`;
|
|
407
|
+
return '—';
|
|
408
|
+
}
|
|
409
|
+
changed(row, parameter) {
|
|
410
|
+
var _a, _b;
|
|
411
|
+
try {
|
|
412
|
+
recalculate(this.parameters, row.measurements, ((_a = this.analysis) === null || _a === void 0 ? void 0 : _a.templateSnapshot.limits) || [], this.businessDate, ((_b = this.analysis) === null || _b === void 0 ? void 0 : _b.oilType) || '');
|
|
413
|
+
}
|
|
414
|
+
catch (e) {
|
|
415
|
+
this.error = e instanceof Error ? e.message : 'Hesaplama yapılamadı.';
|
|
416
|
+
}
|
|
417
|
+
const value = this.measurement(row, parameter);
|
|
418
|
+
const limit = this.limit(parameter);
|
|
419
|
+
value.outOfLimit = !!limit && ((value.number != null &&
|
|
420
|
+
((limit.minimum != null && value.number < limit.minimum) ||
|
|
421
|
+
(limit.maximum != null && value.number > limit.maximum))) ||
|
|
422
|
+
(!!value.text && !!limit.expectedText &&
|
|
423
|
+
value.text.trim().toLocaleLowerCase('tr-TR') !== limit.expectedText.trim().toLocaleLowerCase('tr-TR')));
|
|
424
|
+
}
|
|
425
|
+
oilTypeChanged() {
|
|
426
|
+
var _a;
|
|
427
|
+
for (const row of ((_a = this.analysis) === null || _a === void 0 ? void 0 : _a.hours) || [])
|
|
428
|
+
for (const parameter of this.parameters)
|
|
429
|
+
this.changed(row, parameter);
|
|
430
|
+
}
|
|
431
|
+
average(parameter) {
|
|
432
|
+
var _a;
|
|
433
|
+
const values = ((_a = this.analysis) === null || _a === void 0 ? void 0 : _a.hours.map(h => this.measurement(h, parameter).number).filter((v) => v != null)) || [];
|
|
434
|
+
if (!values.length)
|
|
435
|
+
return '—';
|
|
436
|
+
return (values.reduce((a, b) => a + b, 0) / values.length).toFixed(parameter.decimalPlaces);
|
|
437
|
+
}
|
|
438
|
+
save() {
|
|
439
|
+
if (!this.analysis || !this.editable)
|
|
440
|
+
return;
|
|
441
|
+
this.busy = true;
|
|
442
|
+
this.busyText = 'Form kaydediliyor…';
|
|
443
|
+
this.error = '';
|
|
444
|
+
const input = {
|
|
445
|
+
facilityCode: this.analysis.facilityCode,
|
|
446
|
+
businessDate: this.businessDate,
|
|
447
|
+
oilType: this.analysis.oilType,
|
|
448
|
+
notes: this.analysis.notes,
|
|
449
|
+
revision: this.analysis.revision,
|
|
450
|
+
hours: this.analysis.hours,
|
|
451
|
+
};
|
|
452
|
+
this.api.saveProcess(input).subscribe({
|
|
453
|
+
next: analysis => { this.applyAnalysis(analysis); this.busy = false; },
|
|
454
|
+
error: () => { this.error = 'Form kaydedilemedi. Alanları ve bağlantıyı kontrol edin.'; this.busy = false; },
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
decision(action) {
|
|
458
|
+
if (!this.analysis || !this.analysis.revision)
|
|
459
|
+
return;
|
|
460
|
+
if ((action === 'revoke' || (action === 'approve' && this.hasOutOfLimit)) && !this.reason.trim()) {
|
|
461
|
+
this.reasonError = 'Bu işlem için gerekçe girin.';
|
|
462
|
+
setTimeout(() => { var _a; return (_a = this.reasonInput) === null || _a === void 0 ? void 0 : _a.nativeElement.focus(); });
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
this.busy = true;
|
|
466
|
+
this.busyText = 'İşlem tamamlanıyor…';
|
|
467
|
+
this.error = '';
|
|
468
|
+
this.reasonError = '';
|
|
469
|
+
this.api.decision(this.analysis.code, action, this.analysis.revision, this.reason).subscribe({
|
|
470
|
+
next: analysis => { this.reason = ''; this.applyAnalysis(analysis); this.busy = false; },
|
|
471
|
+
error: () => { this.error = 'İşlem tamamlanamadı. Formun son durumunu kontrol edin.'; this.busy = false; },
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
downloadPdf() {
|
|
475
|
+
var _a;
|
|
476
|
+
if (!((_a = this.analysis) === null || _a === void 0 ? void 0 : _a.revision))
|
|
477
|
+
return;
|
|
478
|
+
this.api.pdf(this.analysis.code).subscribe({
|
|
479
|
+
next: blob => {
|
|
480
|
+
var _a, _b;
|
|
481
|
+
const url = URL.createObjectURL(blob);
|
|
482
|
+
const anchor = document.createElement('a');
|
|
483
|
+
anchor.href = url;
|
|
484
|
+
anchor.download = `${(_a = this.analysis) === null || _a === void 0 ? void 0 : _a.formSnapshot.documentCode}-${(_b = this.analysis) === null || _b === void 0 ? void 0 : _b.code}.pdf`;
|
|
485
|
+
anchor.click();
|
|
486
|
+
setTimeout(() => URL.revokeObjectURL(url), 1000);
|
|
487
|
+
},
|
|
488
|
+
error: () => this.error = 'PDF oluşturulamadı.',
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
today() {
|
|
492
|
+
const date = new Date();
|
|
493
|
+
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
ProcessAnalysisComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ProcessAnalysisComponent, deps: [{ token: QualityApiService }, { token: i2.PermissionService }], target: i0.ɵɵFactoryTarget.Component });
|
|
497
|
+
ProcessAnalysisComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ProcessAnalysisComponent, selector: "lib-process-analysis", viewQueries: [{ propertyName: "reasonInput", first: true, predicate: ["reasonInput"], descendants: true }], ngImport: i0, template: "<div class=\"container-fluid\">\r\n <div class=\"mb-2\">\r\n <h3 class=\"page-title\">Rafineri Proses Analiz Kontrol</h3>\r\n </div>\r\n\r\n <div class=\"card mt-2\"><div class=\"card-body\">\r\n <div class=\"row align-items-end mb-3\">\r\n <div class=\"col-md-3\">\r\n <label for=\"facility\">Tesis</label>\r\n <select id=\"facility\" class=\"form-control\" [disabled]=\"busy\" [(ngModel)]=\"facilityCode\" (change)=\"load()\">\r\n <option *ngFor=\"let facility of facilities\" [value]=\"facility.code\">{{ facility.name }}</option>\r\n </select>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label for=\"businessDate\">\u0130\u015F g\u00FCn\u00FC</label>\r\n <input id=\"businessDate\" type=\"date\" class=\"form-control\" [disabled]=\"busy\" [(ngModel)]=\"businessDate\" (change)=\"load()\" />\r\n </div>\r\n <div class=\"col-md-3\" *ngIf=\"analysis?.facilityCode === 'DEO3'\">\r\n <label for=\"oilType\">\u00DCretilen ya\u011F cinsi</label>\r\n <select id=\"oilType\" class=\"form-control\" [(ngModel)]=\"analysis!.oilType\" (change)=\"oilTypeChanged()\" [disabled]=\"!editable\">\r\n <option value=\"\">Se\u00E7iniz</option><option value=\"Palm Oil\">Palm Oil</option>\r\n <option value=\"Palm Olein\">Palm Olein</option>\r\n </select>\r\n </div>\r\n <div class=\"col-md-3 text-md-right mt-2 mt-md-0\">\r\n <span *ngIf=\"analysis\" class=\"badge badge-info mr-2\" style=\"margin-right: 6px;\">{{ statusText }}</span>\r\n <button class=\"btn btn-outline-primary\" (click)=\"downloadPdf()\" [disabled]=\"!analysis?.revision || busy\"\r\n *ngIf=\"allowed('Print')\">Formu Yazd\u0131r (PDF)</button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"error\" class=\"alert alert-danger\" role=\"alert\">{{ error }}</div>\r\n <div class=\"quality-grid-loading\" *ngIf=\"busy\" role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\r\n <span class=\"spinner-border text-primary\" aria-hidden=\"true\"></span>\r\n <span>{{ busyText }}</span>\r\n </div>\r\n <ng-container *ngIf=\"analysis\">\r\n <div class=\"small text-muted mb-2\">{{ analysis.formSnapshot.name }} \u00B7 {{ analysis.formSnapshot.documentCode }} \u00B7 Revizyon {{ analysis.formSnapshot.revisionNumber }}</div>\r\n <div class=\"quality-grid-scroll\" [hidden]=\"busy\">\r\n <table class=\"table table-bordered table-sm quality-grid\">\r\n <thead>\r\n <tr class=\"text-center bg-light\">\r\n <th rowspan=\"3\" class=\"sticky-hour\">Saat</th><th rowspan=\"3\">Vardiya / Laborant</th>\r\n <th rowspan=\"3\">Al\u0131nan Tank No</th>\r\n <th *ngFor=\"let group of groups\" [attr.colspan]=\"group.parameters.length\">{{ group.step.name }}</th>\r\n <th rowspan=\"3\">Aktar\u0131lan Tank No</th>\r\n </tr>\r\n <tr class=\"text-center bg-light\">\r\n <ng-container *ngFor=\"let group of groups\">\r\n <th *ngFor=\"let parameter of group.parameters\">{{ parameter.name }}<small *ngIf=\"parameter.unit\"> ({{ parameter.unit }})</small></th>\r\n </ng-container>\r\n </tr>\r\n <tr class=\"text-center limit-row\">\r\n <ng-container *ngFor=\"let group of groups\">\r\n <th *ngFor=\"let parameter of group.parameters\">{{ limitLabel(parameter) }}</th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let row of analysis.hours\">\r\n <th class=\"sticky-hour\">{{ row.hour | number:'2.0-0' }}:00</th><td><small>{{row.shiftCode}}</small><input class=\"form-control form-control-sm\" [(ngModel)]=\"row.analyst\" [disabled]=\"!editable\" aria-label=\"Vardiya laborant\u0131\" /></td>\r\n <td><input class=\"form-control form-control-sm tank-input\" list=\"qualityTanks\" [(ngModel)]=\"row.intakeTank\" [disabled]=\"!editable\" aria-label=\"Al\u0131nan tank\" /></td>\r\n <ng-container *ngFor=\"let group of groups\">\r\n <td *ngFor=\"let parameter of group.parameters\" [class.out-of-limit]=\"measurement(row, parameter).outOfLimit\">\r\n <input *ngIf=\"parameter.valueType === 'Number' || parameter.calculated\" type=\"number\"\r\n class=\"form-control form-control-sm value-input\" [attr.step]=\"'any'\"\r\n [(ngModel)]=\"measurement(row, parameter).number\" (ngModelChange)=\"changed(row, parameter)\"\r\n [disabled]=\"!editable || parameter.calculated\" [attr.aria-label]=\"parameter.name\" />\r\n <select *ngIf=\"parameter.valueType === 'Choice' && !parameter.calculated\" class=\"form-control form-control-sm value-input\"\r\n [(ngModel)]=\"measurement(row, parameter).text\" (change)=\"changed(row, parameter)\" [disabled]=\"!editable\">\r\n <option value=\"\"></option><option *ngFor=\"let option of parameter.options\" [value]=\"option\">{{ option }}</option>\r\n </select>\r\n <input *ngIf=\"parameter.valueType === 'Text' && !parameter.calculated\" class=\"form-control form-control-sm value-input\"\r\n [(ngModel)]=\"measurement(row, parameter).text\" (ngModelChange)=\"changed(row, parameter)\" [disabled]=\"!editable\"\r\n [attr.aria-label]=\"parameter.name\" />\r\n </td>\r\n </ng-container>\r\n <td><input class=\"form-control form-control-sm tank-input\" list=\"qualityTanks\" [(ngModel)]=\"row.outputTank\" [disabled]=\"!editable\" aria-label=\"Aktar\u0131lan tank\" /></td>\r\n </tr>\r\n <tr class=\"average-row\">\r\n <th colspan=\"3\">ORTALAMA</th>\r\n <ng-container *ngFor=\"let group of groups\">\r\n <td *ngFor=\"let parameter of group.parameters\">{{ parameter.valueType === 'Number' ? average(parameter) : '\u2014' }}</td>\r\n </ng-container>\r\n <td></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div class=\"row mt-3\">\r\n <div class=\"col-md-6\">\r\n <label for=\"notes\">{{ analysis.formSnapshot.code === 'FR52' ? 'A\u00E7\u0131klama / Bilgi' : 'Notlar' }}</label>\r\n <textarea id=\"notes\" class=\"form-control\" rows=\"3\" [(ngModel)]=\"analysis.notes\" [disabled]=\"!editable\"></textarea>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label for=\"reason\">Onay / geri alma gerek\u00E7esi</label>\r\n <textarea #reasonInput id=\"reason\" class=\"form-control\" rows=\"3\" [(ngModel)]=\"reason\" (ngModelChange)=\"reasonError = ''\"\r\n [class.is-invalid]=\"reasonError\" [attr.aria-invalid]=\"!!reasonError\"\r\n [disabled]=\"busy || analysis.status === 'LaborantSigned'\"></textarea>\r\n <div *ngIf=\"reasonError\" class=\"invalid-feedback d-block\" role=\"alert\">{{ reasonError }}</div>\r\n </div>\r\n </div>\r\n <div class=\"mt-3 d-flex flex-wrap align-items-center gap-2\">\r\n <button class=\"btn btn-primary mr-2 mb-2\" (click)=\"save()\" [disabled]=\"!editable || busy\">Kaydet</button>\r\n <button class=\"btn btn-outline-primary mr-2 mb-2\" *ngIf=\"analysis.status === 'Draft' && allowed('Sign')\"\r\n (click)=\"decision('sign')\" [disabled]=\"!analysis.revision || busy\">Laborant Olarak \u0130mzala</button>\r\n <button class=\"btn btn-outline-primary mr-2 mb-2\" *ngIf=\"analysis.status === 'LaborantSigned' && allowed('Check')\"\r\n (click)=\"decision('check')\" [disabled]=\"busy\">M\u00FChendis Kontrol\u00FC</button>\r\n <button class=\"btn btn-success mr-2 mb-2\" *ngIf=\"analysis.status === 'Checked' && allowed('Approve')\"\r\n (click)=\"decision('approve')\" [disabled]=\"busy\">Son Onay</button>\r\n <button class=\"btn btn-outline-danger mr-2 mb-2\" *ngIf=\"analysis.status === 'Approved' && allowed('Revoke')\"\r\n (click)=\"decision('revoke')\" [disabled]=\"busy\">Onay\u0131 Geri Al</button>\r\n <span *ngIf=\"hasOutOfLimit\" class=\"text-danger mb-2\">Limit d\u0131\u015F\u0131 \u00F6l\u00E7\u00FCm var. Son onay i\u00E7in gerek\u00E7e gerekli.</span>\r\n </div>\r\n <div class=\"mt-3 small text-muted\">\r\n <span>Laborant: {{ analysis.laborant?.userName || '\u2014' }}</span> \u00B7\r\n <span>M\u00FChendis: {{ analysis.engineer?.userName || '\u2014' }}</span> \u00B7\r\n <span>Onaylayan: {{ analysis.approver?.userName || '\u2014' }}</span>\r\n </div>\r\n <details class=\"mt-3\" *ngIf=\"analysis.history?.length\">\r\n <summary>\u0130\u015Flem ge\u00E7mi\u015Fi</summary>\r\n <ul class=\"mt-2\"><li *ngFor=\"let event of analysis.history\">{{ event.action }} \u00B7 {{ event.userName }} \u00B7 {{ event.occurredAt | date:'dd.MM.yyyy HH:mm' }}<span *ngIf=\"event.reason\"> \u00B7 {{ event.reason }}</span></li></ul>\r\n </details>\r\n </ng-container>\r\n </div></div>\r\n</div>\r\n\r\n<datalist id=\"qualityTanks\"><option *ngFor=\"let tank of tanks\" [value]=\"tank.code\">{{tank.name}}</option></datalist>\r\n", styles: [".quality-grid-scroll{overflow:auto;max-height:calc(100vh - 340px)}.quality-grid{width:max-content;min-width:100%;table-layout:fixed}.quality-grid th,.quality-grid td{min-width:105px;vertical-align:middle;white-space:nowrap}.quality-grid .sticky-hour{position:sticky;left:0;z-index:2;min-width:72px;background:#f8f9fa}.quality-grid thead{position:sticky;top:0;z-index:3}.quality-grid thead th{background:#f8f9fa}.quality-grid thead .sticky-hour{z-index:4}.quality-grid .value-input{min-width:90px;width:100%}.quality-grid .tank-input{min-width:110px;width:100%}.quality-grid .limit-row{color:#6f42a4;font-size:.82rem}.quality-grid .out-of-limit{background:#ffe0e0}.quality-grid .out-of-limit input,.quality-grid .out-of-limit select{border-color:#d33}.quality-grid .average-row{background:#fff8d8;font-weight:600}.quality-grid-loading{min-height:280px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;background:#f8f9fa;border:1px solid #dee2e6;border-radius:4px;color:#495057}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.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: i5.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i3.DecimalPipe, name: "number" }, { kind: "pipe", type: i3.DatePipe, name: "date" }] });
|
|
498
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ProcessAnalysisComponent, decorators: [{
|
|
499
|
+
type: Component,
|
|
500
|
+
args: [{ selector: 'lib-process-analysis', template: "<div class=\"container-fluid\">\r\n <div class=\"mb-2\">\r\n <h3 class=\"page-title\">Rafineri Proses Analiz Kontrol</h3>\r\n </div>\r\n\r\n <div class=\"card mt-2\"><div class=\"card-body\">\r\n <div class=\"row align-items-end mb-3\">\r\n <div class=\"col-md-3\">\r\n <label for=\"facility\">Tesis</label>\r\n <select id=\"facility\" class=\"form-control\" [disabled]=\"busy\" [(ngModel)]=\"facilityCode\" (change)=\"load()\">\r\n <option *ngFor=\"let facility of facilities\" [value]=\"facility.code\">{{ facility.name }}</option>\r\n </select>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label for=\"businessDate\">\u0130\u015F g\u00FCn\u00FC</label>\r\n <input id=\"businessDate\" type=\"date\" class=\"form-control\" [disabled]=\"busy\" [(ngModel)]=\"businessDate\" (change)=\"load()\" />\r\n </div>\r\n <div class=\"col-md-3\" *ngIf=\"analysis?.facilityCode === 'DEO3'\">\r\n <label for=\"oilType\">\u00DCretilen ya\u011F cinsi</label>\r\n <select id=\"oilType\" class=\"form-control\" [(ngModel)]=\"analysis!.oilType\" (change)=\"oilTypeChanged()\" [disabled]=\"!editable\">\r\n <option value=\"\">Se\u00E7iniz</option><option value=\"Palm Oil\">Palm Oil</option>\r\n <option value=\"Palm Olein\">Palm Olein</option>\r\n </select>\r\n </div>\r\n <div class=\"col-md-3 text-md-right mt-2 mt-md-0\">\r\n <span *ngIf=\"analysis\" class=\"badge badge-info mr-2\" style=\"margin-right: 6px;\">{{ statusText }}</span>\r\n <button class=\"btn btn-outline-primary\" (click)=\"downloadPdf()\" [disabled]=\"!analysis?.revision || busy\"\r\n *ngIf=\"allowed('Print')\">Formu Yazd\u0131r (PDF)</button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"error\" class=\"alert alert-danger\" role=\"alert\">{{ error }}</div>\r\n <div class=\"quality-grid-loading\" *ngIf=\"busy\" role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\r\n <span class=\"spinner-border text-primary\" aria-hidden=\"true\"></span>\r\n <span>{{ busyText }}</span>\r\n </div>\r\n <ng-container *ngIf=\"analysis\">\r\n <div class=\"small text-muted mb-2\">{{ analysis.formSnapshot.name }} \u00B7 {{ analysis.formSnapshot.documentCode }} \u00B7 Revizyon {{ analysis.formSnapshot.revisionNumber }}</div>\r\n <div class=\"quality-grid-scroll\" [hidden]=\"busy\">\r\n <table class=\"table table-bordered table-sm quality-grid\">\r\n <thead>\r\n <tr class=\"text-center bg-light\">\r\n <th rowspan=\"3\" class=\"sticky-hour\">Saat</th><th rowspan=\"3\">Vardiya / Laborant</th>\r\n <th rowspan=\"3\">Al\u0131nan Tank No</th>\r\n <th *ngFor=\"let group of groups\" [attr.colspan]=\"group.parameters.length\">{{ group.step.name }}</th>\r\n <th rowspan=\"3\">Aktar\u0131lan Tank No</th>\r\n </tr>\r\n <tr class=\"text-center bg-light\">\r\n <ng-container *ngFor=\"let group of groups\">\r\n <th *ngFor=\"let parameter of group.parameters\">{{ parameter.name }}<small *ngIf=\"parameter.unit\"> ({{ parameter.unit }})</small></th>\r\n </ng-container>\r\n </tr>\r\n <tr class=\"text-center limit-row\">\r\n <ng-container *ngFor=\"let group of groups\">\r\n <th *ngFor=\"let parameter of group.parameters\">{{ limitLabel(parameter) }}</th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let row of analysis.hours\">\r\n <th class=\"sticky-hour\">{{ row.hour | number:'2.0-0' }}:00</th><td><small>{{row.shiftCode}}</small><input class=\"form-control form-control-sm\" [(ngModel)]=\"row.analyst\" [disabled]=\"!editable\" aria-label=\"Vardiya laborant\u0131\" /></td>\r\n <td><input class=\"form-control form-control-sm tank-input\" list=\"qualityTanks\" [(ngModel)]=\"row.intakeTank\" [disabled]=\"!editable\" aria-label=\"Al\u0131nan tank\" /></td>\r\n <ng-container *ngFor=\"let group of groups\">\r\n <td *ngFor=\"let parameter of group.parameters\" [class.out-of-limit]=\"measurement(row, parameter).outOfLimit\">\r\n <input *ngIf=\"parameter.valueType === 'Number' || parameter.calculated\" type=\"number\"\r\n class=\"form-control form-control-sm value-input\" [attr.step]=\"'any'\"\r\n [(ngModel)]=\"measurement(row, parameter).number\" (ngModelChange)=\"changed(row, parameter)\"\r\n [disabled]=\"!editable || parameter.calculated\" [attr.aria-label]=\"parameter.name\" />\r\n <select *ngIf=\"parameter.valueType === 'Choice' && !parameter.calculated\" class=\"form-control form-control-sm value-input\"\r\n [(ngModel)]=\"measurement(row, parameter).text\" (change)=\"changed(row, parameter)\" [disabled]=\"!editable\">\r\n <option value=\"\"></option><option *ngFor=\"let option of parameter.options\" [value]=\"option\">{{ option }}</option>\r\n </select>\r\n <input *ngIf=\"parameter.valueType === 'Text' && !parameter.calculated\" class=\"form-control form-control-sm value-input\"\r\n [(ngModel)]=\"measurement(row, parameter).text\" (ngModelChange)=\"changed(row, parameter)\" [disabled]=\"!editable\"\r\n [attr.aria-label]=\"parameter.name\" />\r\n </td>\r\n </ng-container>\r\n <td><input class=\"form-control form-control-sm tank-input\" list=\"qualityTanks\" [(ngModel)]=\"row.outputTank\" [disabled]=\"!editable\" aria-label=\"Aktar\u0131lan tank\" /></td>\r\n </tr>\r\n <tr class=\"average-row\">\r\n <th colspan=\"3\">ORTALAMA</th>\r\n <ng-container *ngFor=\"let group of groups\">\r\n <td *ngFor=\"let parameter of group.parameters\">{{ parameter.valueType === 'Number' ? average(parameter) : '\u2014' }}</td>\r\n </ng-container>\r\n <td></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div class=\"row mt-3\">\r\n <div class=\"col-md-6\">\r\n <label for=\"notes\">{{ analysis.formSnapshot.code === 'FR52' ? 'A\u00E7\u0131klama / Bilgi' : 'Notlar' }}</label>\r\n <textarea id=\"notes\" class=\"form-control\" rows=\"3\" [(ngModel)]=\"analysis.notes\" [disabled]=\"!editable\"></textarea>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label for=\"reason\">Onay / geri alma gerek\u00E7esi</label>\r\n <textarea #reasonInput id=\"reason\" class=\"form-control\" rows=\"3\" [(ngModel)]=\"reason\" (ngModelChange)=\"reasonError = ''\"\r\n [class.is-invalid]=\"reasonError\" [attr.aria-invalid]=\"!!reasonError\"\r\n [disabled]=\"busy || analysis.status === 'LaborantSigned'\"></textarea>\r\n <div *ngIf=\"reasonError\" class=\"invalid-feedback d-block\" role=\"alert\">{{ reasonError }}</div>\r\n </div>\r\n </div>\r\n <div class=\"mt-3 d-flex flex-wrap align-items-center gap-2\">\r\n <button class=\"btn btn-primary mr-2 mb-2\" (click)=\"save()\" [disabled]=\"!editable || busy\">Kaydet</button>\r\n <button class=\"btn btn-outline-primary mr-2 mb-2\" *ngIf=\"analysis.status === 'Draft' && allowed('Sign')\"\r\n (click)=\"decision('sign')\" [disabled]=\"!analysis.revision || busy\">Laborant Olarak \u0130mzala</button>\r\n <button class=\"btn btn-outline-primary mr-2 mb-2\" *ngIf=\"analysis.status === 'LaborantSigned' && allowed('Check')\"\r\n (click)=\"decision('check')\" [disabled]=\"busy\">M\u00FChendis Kontrol\u00FC</button>\r\n <button class=\"btn btn-success mr-2 mb-2\" *ngIf=\"analysis.status === 'Checked' && allowed('Approve')\"\r\n (click)=\"decision('approve')\" [disabled]=\"busy\">Son Onay</button>\r\n <button class=\"btn btn-outline-danger mr-2 mb-2\" *ngIf=\"analysis.status === 'Approved' && allowed('Revoke')\"\r\n (click)=\"decision('revoke')\" [disabled]=\"busy\">Onay\u0131 Geri Al</button>\r\n <span *ngIf=\"hasOutOfLimit\" class=\"text-danger mb-2\">Limit d\u0131\u015F\u0131 \u00F6l\u00E7\u00FCm var. Son onay i\u00E7in gerek\u00E7e gerekli.</span>\r\n </div>\r\n <div class=\"mt-3 small text-muted\">\r\n <span>Laborant: {{ analysis.laborant?.userName || '\u2014' }}</span> \u00B7\r\n <span>M\u00FChendis: {{ analysis.engineer?.userName || '\u2014' }}</span> \u00B7\r\n <span>Onaylayan: {{ analysis.approver?.userName || '\u2014' }}</span>\r\n </div>\r\n <details class=\"mt-3\" *ngIf=\"analysis.history?.length\">\r\n <summary>\u0130\u015Flem ge\u00E7mi\u015Fi</summary>\r\n <ul class=\"mt-2\"><li *ngFor=\"let event of analysis.history\">{{ event.action }} \u00B7 {{ event.userName }} \u00B7 {{ event.occurredAt | date:'dd.MM.yyyy HH:mm' }}<span *ngIf=\"event.reason\"> \u00B7 {{ event.reason }}</span></li></ul>\r\n </details>\r\n </ng-container>\r\n </div></div>\r\n</div>\r\n\r\n<datalist id=\"qualityTanks\"><option *ngFor=\"let tank of tanks\" [value]=\"tank.code\">{{tank.name}}</option></datalist>\r\n", styles: [".quality-grid-scroll{overflow:auto;max-height:calc(100vh - 340px)}.quality-grid{width:max-content;min-width:100%;table-layout:fixed}.quality-grid th,.quality-grid td{min-width:105px;vertical-align:middle;white-space:nowrap}.quality-grid .sticky-hour{position:sticky;left:0;z-index:2;min-width:72px;background:#f8f9fa}.quality-grid thead{position:sticky;top:0;z-index:3}.quality-grid thead th{background:#f8f9fa}.quality-grid thead .sticky-hour{z-index:4}.quality-grid .value-input{min-width:90px;width:100%}.quality-grid .tank-input{min-width:110px;width:100%}.quality-grid .limit-row{color:#6f42a4;font-size:.82rem}.quality-grid .out-of-limit{background:#ffe0e0}.quality-grid .out-of-limit input,.quality-grid .out-of-limit select{border-color:#d33}.quality-grid .average-row{background:#fff8d8;font-weight:600}.quality-grid-loading{min-height:280px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;background:#f8f9fa;border:1px solid #dee2e6;border-radius:4px;color:#495057}\n"] }]
|
|
501
|
+
}], ctorParameters: function () { return [{ type: QualityApiService }, { type: i2.PermissionService }]; }, propDecorators: { reasonInput: [{
|
|
502
|
+
type: ViewChild,
|
|
503
|
+
args: ['reasonInput']
|
|
504
|
+
}] } });
|
|
505
|
+
|
|
506
|
+
class QualityParametersComponent {
|
|
507
|
+
constructor(api, permissions, changeDetector, route) {
|
|
508
|
+
this.api = api;
|
|
509
|
+
this.permissions = permissions;
|
|
510
|
+
this.changeDetector = changeDetector;
|
|
511
|
+
this.route = route;
|
|
512
|
+
this.controlType = 'Process';
|
|
513
|
+
this.movementTypes = [];
|
|
514
|
+
this.movementDetails = [];
|
|
515
|
+
this.movementTypeCode = '';
|
|
516
|
+
this.movementDetailCode = '';
|
|
517
|
+
this.newInputForm = false;
|
|
518
|
+
this.forms = [];
|
|
519
|
+
this.facilities = [];
|
|
520
|
+
this.facilityCode = '';
|
|
521
|
+
this.facilitySteps = [];
|
|
522
|
+
this.editingStep = null;
|
|
523
|
+
this.newStep = false;
|
|
524
|
+
this.formCode = '';
|
|
525
|
+
this.template = null;
|
|
526
|
+
this.editingParameter = null;
|
|
527
|
+
this.editingLimit = null;
|
|
528
|
+
this.newParameter = false;
|
|
529
|
+
this.newLimit = false;
|
|
530
|
+
this.parameterModalVisible = false;
|
|
531
|
+
this.limitModalVisible = false;
|
|
532
|
+
this.modalError = '';
|
|
533
|
+
this.editorModalOptions = { size: 'xl', centered: true };
|
|
534
|
+
this.optionsText = '';
|
|
535
|
+
this.pendingRequests = 0;
|
|
536
|
+
this.busyText = 'Kalite tanımları yükleniyor…';
|
|
537
|
+
this.error = '';
|
|
538
|
+
this.success = '';
|
|
539
|
+
}
|
|
540
|
+
get busy() { return this.pendingRequests > 0; }
|
|
541
|
+
ngOnInit() {
|
|
542
|
+
if (this.route.snapshot.queryParamMap.get('type') === 'Input')
|
|
543
|
+
this.controlType = 'Input';
|
|
544
|
+
this.movementDetailCode = this.route.snapshot.queryParamMap.get('detail') || '';
|
|
545
|
+
this.api.qualityMovementTypes().subscribe({ next: x => this.movementTypes = x, error: e => this.error = errorMessage(e) });
|
|
546
|
+
this.api.movementDetails().subscribe({ next: x => {
|
|
547
|
+
var _a;
|
|
548
|
+
this.movementDetails = x.filter(d => d.active);
|
|
549
|
+
this.movementTypeCode = ((_a = x.find(d => d.code === this.movementDetailCode)) === null || _a === void 0 ? void 0 : _a.movementTypeCode) || '';
|
|
550
|
+
if (this.controlType === 'Input')
|
|
551
|
+
this.selectInput();
|
|
552
|
+
}, error: e => this.error = errorMessage(e) });
|
|
553
|
+
this.track(this.api.parameterFacilities(), 'Kalite tanımları yükleniyor…').subscribe({
|
|
554
|
+
next: facilities => {
|
|
555
|
+
this.facilities = facilities;
|
|
556
|
+
this.selectFacility();
|
|
557
|
+
if (this.facilityCode)
|
|
558
|
+
this.loadSteps();
|
|
559
|
+
},
|
|
560
|
+
error: () => this.error = 'Tesis listesi yüklenemedi.',
|
|
561
|
+
});
|
|
562
|
+
this.track(this.api.forms(), 'Kalite tanımları yükleniyor…').subscribe({
|
|
563
|
+
next: forms => { this.forms = forms; this.switchType(this.controlType); },
|
|
564
|
+
error: () => this.error = 'Form listesi yüklenemedi.',
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
get canEdit() { return this.permissions.getGrantedPolicy('Kalite.Parameters.Edit'); }
|
|
568
|
+
get canCreate() { return this.permissions.getGrantedPolicy('Kalite.Parameters.Create'); }
|
|
569
|
+
get canDelete() { return this.permissions.getGrantedPolicy('Kalite.Parameters.Delete'); }
|
|
570
|
+
get visibleForms() { return this.forms.filter(f => (f.controlType || 'Process') === this.controlType); }
|
|
571
|
+
get visibleDetails() { return this.movementDetails.filter(d => !this.movementTypeCode || d.movementTypeCode === this.movementTypeCode); }
|
|
572
|
+
switchType(type) {
|
|
573
|
+
var _a;
|
|
574
|
+
this.controlType = type;
|
|
575
|
+
this.editingStep = null;
|
|
576
|
+
this.facilitySteps = [];
|
|
577
|
+
this.template = null;
|
|
578
|
+
if (type === 'Input')
|
|
579
|
+
this.selectInput();
|
|
580
|
+
else {
|
|
581
|
+
this.formCode = ((_a = this.visibleForms[0]) === null || _a === void 0 ? void 0 : _a.code) || '';
|
|
582
|
+
this.newInputForm = false;
|
|
583
|
+
this.load();
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
selectInput() {
|
|
587
|
+
var _a, _b;
|
|
588
|
+
if (!this.visibleDetails.some(d => d.code === this.movementDetailCode))
|
|
589
|
+
this.movementDetailCode = ((_a = this.visibleDetails[0]) === null || _a === void 0 ? void 0 : _a.code) || '';
|
|
590
|
+
const form = this.visibleForms.find(f => f.movementDetailCode === this.movementDetailCode);
|
|
591
|
+
if (form) {
|
|
592
|
+
this.formCode = form.code;
|
|
593
|
+
this.newInputForm = false;
|
|
594
|
+
this.load();
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
const detail = this.movementDetails.find(d => d.code === this.movementDetailCode);
|
|
598
|
+
this.newInputForm = !!detail;
|
|
599
|
+
this.formCode = detail ? 'IN_' + detail.code : '';
|
|
600
|
+
this.template = detail ? { form: { code: this.formCode, controlType: 'Input', movementDetailCode: detail.code,
|
|
601
|
+
averageMode: 'Arithmetic', name: detail.name || ((_b = this.movementTypes.find(t => t.code === detail.movementTypeCode)) === null || _b === void 0 ? void 0 : _b.name) || '',
|
|
602
|
+
documentCode: '', publicationDate: localDate(), revisionDate: localDate(), revisionNumber: '1', active: true },
|
|
603
|
+
parameters: [], limits: [], steps: [] } : null;
|
|
604
|
+
}
|
|
605
|
+
load() {
|
|
606
|
+
if (!this.formCode)
|
|
607
|
+
return;
|
|
608
|
+
if (this.controlType === 'Process') {
|
|
609
|
+
this.selectFacility();
|
|
610
|
+
if (this.facilityCode)
|
|
611
|
+
this.loadSteps();
|
|
612
|
+
}
|
|
613
|
+
this.error = '';
|
|
614
|
+
this.track(this.api.template(this.formCode), 'Kalite tanımları yükleniyor…').subscribe({
|
|
615
|
+
next: template => {
|
|
616
|
+
var _a, _b;
|
|
617
|
+
template.form.publicationDate = (_a = template.form.publicationDate) === null || _a === void 0 ? void 0 : _a.slice(0, 10);
|
|
618
|
+
template.form.revisionDate = (_b = template.form.revisionDate) === null || _b === void 0 ? void 0 : _b.slice(0, 10);
|
|
619
|
+
this.template = template;
|
|
620
|
+
this.editingParameter = null;
|
|
621
|
+
this.editingLimit = null;
|
|
622
|
+
},
|
|
623
|
+
error: () => { this.error = 'Form tanımı yüklenemedi.'; },
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
revealStepEditor() {
|
|
627
|
+
var _a, _b;
|
|
628
|
+
this.changeDetector.detectChanges();
|
|
629
|
+
(_a = this.stepEditor) === null || _a === void 0 ? void 0 : _a.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
630
|
+
(_b = this.stepEditor) === null || _b === void 0 ? void 0 : _b.nativeElement.focus({ preventScroll: true });
|
|
631
|
+
}
|
|
632
|
+
parameterModalChanged(visible) {
|
|
633
|
+
this.parameterModalVisible = visible;
|
|
634
|
+
if (!visible) {
|
|
635
|
+
this.editingParameter = null;
|
|
636
|
+
this.modalError = '';
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
limitModalChanged(visible) {
|
|
640
|
+
this.limitModalVisible = visible;
|
|
641
|
+
if (!visible) {
|
|
642
|
+
this.editingLimit = null;
|
|
643
|
+
this.modalError = '';
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
closeParameterModal() {
|
|
647
|
+
if (!this.busy)
|
|
648
|
+
this.parameterModalChanged(false);
|
|
649
|
+
}
|
|
650
|
+
closeLimitModal() {
|
|
651
|
+
if (!this.busy)
|
|
652
|
+
this.limitModalChanged(false);
|
|
653
|
+
}
|
|
654
|
+
track(request, message) {
|
|
655
|
+
return defer(() => {
|
|
656
|
+
this.pendingRequests++;
|
|
657
|
+
this.busyText = message;
|
|
658
|
+
return request.pipe(finalize(() => this.pendingRequests--));
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
processName(code) {
|
|
662
|
+
var _a, _b;
|
|
663
|
+
return ((_b = (_a = this.template) === null || _a === void 0 ? void 0 : _a.steps.find(step => step.processCode === code)) === null || _b === void 0 ? void 0 : _b.name) || code;
|
|
664
|
+
}
|
|
665
|
+
steps() {
|
|
666
|
+
return this.facilitySteps.filter(x => x.active);
|
|
667
|
+
}
|
|
668
|
+
matchingFacilities() {
|
|
669
|
+
return this.facilities.filter(x => x.formCode === this.formCode);
|
|
670
|
+
}
|
|
671
|
+
selectFacility() {
|
|
672
|
+
var _a;
|
|
673
|
+
if (!this.matchingFacilities().some(x => x.code === this.facilityCode))
|
|
674
|
+
this.facilityCode = ((_a = this.matchingFacilities()[0]) === null || _a === void 0 ? void 0 : _a.code) || '';
|
|
675
|
+
}
|
|
676
|
+
loadSteps() {
|
|
677
|
+
if (!this.facilityCode)
|
|
678
|
+
return;
|
|
679
|
+
this.track(this.api.steps(this.facilityCode), 'Kalite tanımları yükleniyor…').subscribe({
|
|
680
|
+
next: steps => this.facilitySteps = steps,
|
|
681
|
+
error: () => this.error = 'Proses adımları yüklenemedi.',
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
addStep() {
|
|
685
|
+
this.newStep = true;
|
|
686
|
+
this.editingStep = { code: '', facilityCode: this.facilityCode, processCode: '',
|
|
687
|
+
name: '', order: this.facilitySteps.length + 1, active: true };
|
|
688
|
+
this.revealStepEditor();
|
|
689
|
+
}
|
|
690
|
+
editStep(step) {
|
|
691
|
+
this.newStep = false;
|
|
692
|
+
this.editingStep = Object.assign({}, step);
|
|
693
|
+
this.revealStepEditor();
|
|
694
|
+
}
|
|
695
|
+
saveStep() {
|
|
696
|
+
if (!this.editingStep)
|
|
697
|
+
return;
|
|
698
|
+
const step = Object.assign(Object.assign({}, this.editingStep), { code: this.editingStep.code.trim().toUpperCase(), processCode: this.editingStep.processCode.trim().toUpperCase(), name: this.editingStep.name.trim() });
|
|
699
|
+
this.track(this.api.saveStep(step), 'Değişiklikler kaydediliyor…').subscribe({
|
|
700
|
+
next: () => { this.editingStep = null; this.success = 'Proses adımı kaydedildi.'; this.loadSteps(); },
|
|
701
|
+
error: () => { this.error = 'Proses adımı kaydedilemedi.'; },
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
orderedParameters() {
|
|
705
|
+
var _a;
|
|
706
|
+
const order = this.steps().map(step => step.processCode);
|
|
707
|
+
return [...(((_a = this.template) === null || _a === void 0 ? void 0 : _a.parameters) || [])].sort((a, b) => order.indexOf(a.stepCode) - order.indexOf(b.stepCode) || a.order - b.order);
|
|
708
|
+
}
|
|
709
|
+
limitsFor(code) {
|
|
710
|
+
var _a;
|
|
711
|
+
return ((_a = this.template) === null || _a === void 0 ? void 0 : _a.limits.filter(limit => limit.parameterCode === code)) || [];
|
|
712
|
+
}
|
|
713
|
+
editForm() {
|
|
714
|
+
if (!this.template || !this.canEdit)
|
|
715
|
+
return;
|
|
716
|
+
this.track(this.api.saveForm(this.template.form), 'Değişiklikler kaydediliyor…').subscribe({
|
|
717
|
+
next: () => {
|
|
718
|
+
this.success = 'Form başlığı kaydedildi.';
|
|
719
|
+
this.newInputForm = false;
|
|
720
|
+
this.api.forms().subscribe({ next: forms => { this.forms = forms; this.load(); } });
|
|
721
|
+
},
|
|
722
|
+
error: () => { this.error = 'Form başlığı kaydedilemedi.'; },
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
addParameter() {
|
|
726
|
+
var _a;
|
|
727
|
+
if (!this.template || this.newInputForm)
|
|
728
|
+
return;
|
|
729
|
+
this.newParameter = true;
|
|
730
|
+
this.optionsText = '';
|
|
731
|
+
this.editingParameter = {
|
|
732
|
+
code: '', formCode: this.formCode, stepCode: ((_a = this.template.steps[0]) === null || _a === void 0 ? void 0 : _a.processCode) || '',
|
|
733
|
+
order: this.template.parameters.length + 1, name: '', unit: '', valueType: 'Number',
|
|
734
|
+
decimalPlaces: 2, required: false, calculated: false, formula: '', options: [], active: true,
|
|
735
|
+
};
|
|
736
|
+
this.editingLimit = null;
|
|
737
|
+
this.modalError = '';
|
|
738
|
+
this.parameterModalVisible = true;
|
|
739
|
+
}
|
|
740
|
+
editParameter(parameter) {
|
|
741
|
+
this.newParameter = false;
|
|
742
|
+
this.editingParameter = Object.assign(Object.assign({}, parameter), { options: [...(parameter.options || [])] });
|
|
743
|
+
this.optionsText = this.editingParameter.options.join(', ');
|
|
744
|
+
this.editingLimit = null;
|
|
745
|
+
this.modalError = '';
|
|
746
|
+
this.parameterModalVisible = true;
|
|
747
|
+
}
|
|
748
|
+
saveParameter() {
|
|
749
|
+
if (!this.editingParameter || this.busy)
|
|
750
|
+
return;
|
|
751
|
+
const parameter = Object.assign(Object.assign({}, this.editingParameter), { code: this.editingParameter.code.trim().toUpperCase(), name: this.editingParameter.name.trim(), options: this.optionsText.split(',').map(x => x.trim()).filter(Boolean) });
|
|
752
|
+
if (!parameter.code || !parameter.name || (this.controlType === 'Process' && !parameter.stepCode)) {
|
|
753
|
+
this.modalError = 'Parametre kodu, adı ve proses kontrolünde proses adımı zorunludur.';
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
this.modalError = '';
|
|
757
|
+
const request = this.newParameter ? this.api.createParameter(parameter) : this.api.updateParameter(parameter);
|
|
758
|
+
this.track(request, 'Değişiklikler kaydediliyor…').subscribe({
|
|
759
|
+
next: () => { this.parameterModalChanged(false); this.success = 'Parametre kaydedildi.'; this.load(); },
|
|
760
|
+
error: () => { this.modalError = 'Parametre kaydedilemedi.'; },
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
deleteParameter(parameter) {
|
|
764
|
+
if (!confirm(`${parameter.name} parametresi ve bağlı limitleri kalıcı olarak silinsin mi?`))
|
|
765
|
+
return;
|
|
766
|
+
this.track(this.api.deleteParameter(parameter.code), 'Değişiklikler kaydediliyor…').subscribe({
|
|
767
|
+
next: () => this.load(), error: e => this.error = errorMessage(e),
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
addLimit(parameter) {
|
|
771
|
+
this.newLimit = true;
|
|
772
|
+
this.editingParameter = null;
|
|
773
|
+
this.editingLimit = {
|
|
774
|
+
code: '', parameterCode: parameter.code, oilType: '', origin: '', minimum: null, maximum: null,
|
|
775
|
+
nominal: null, expectedText: '', validFrom: null, validUntil: null, active: true,
|
|
776
|
+
};
|
|
777
|
+
this.modalError = '';
|
|
778
|
+
this.limitModalVisible = true;
|
|
779
|
+
}
|
|
780
|
+
editLimit(limit) {
|
|
781
|
+
var _a, _b;
|
|
782
|
+
this.newLimit = false;
|
|
783
|
+
this.editingParameter = null;
|
|
784
|
+
this.editingLimit = Object.assign(Object.assign({}, limit), { validFrom: ((_a = limit.validFrom) === null || _a === void 0 ? void 0 : _a.slice(0, 10)) || null, validUntil: ((_b = limit.validUntil) === null || _b === void 0 ? void 0 : _b.slice(0, 10)) || null });
|
|
785
|
+
this.modalError = '';
|
|
786
|
+
this.limitModalVisible = true;
|
|
787
|
+
}
|
|
788
|
+
saveLimit() {
|
|
789
|
+
var _a;
|
|
790
|
+
if (!this.editingLimit || this.busy)
|
|
791
|
+
return;
|
|
792
|
+
const limit = Object.assign(Object.assign({}, this.editingLimit), { code: this.newLimit ? this.editingLimit.code.trim().toUpperCase() : this.editingLimit.code, oilType: ((_a = this.editingLimit.oilType) === null || _a === void 0 ? void 0 : _a.trim()) || '' });
|
|
793
|
+
if (!limit.code) {
|
|
794
|
+
this.modalError = 'Limit kodu zorunludur.';
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
this.modalError = '';
|
|
798
|
+
const request = this.newLimit ? this.api.createLimit(limit) : this.api.updateLimit(limit);
|
|
799
|
+
this.track(request, 'Değişiklikler kaydediliyor…').subscribe({
|
|
800
|
+
next: () => { this.limitModalChanged(false); this.success = 'Limit kaydedildi.'; this.load(); },
|
|
801
|
+
error: e => { this.modalError = errorMessage(e); },
|
|
802
|
+
});
|
|
803
|
+
}
|
|
804
|
+
deleteLimit(limit) {
|
|
805
|
+
if (this.busy)
|
|
806
|
+
return;
|
|
807
|
+
if (!confirm(`${limit.code} limiti kalıcı olarak silinsin mi?`))
|
|
808
|
+
return;
|
|
809
|
+
this.track(this.api.deleteLimit(limit.code), 'Değişiklikler kaydediliyor…').subscribe({
|
|
810
|
+
next: () => { this.limitModalChanged(false); this.load(); },
|
|
811
|
+
error: e => {
|
|
812
|
+
if (this.limitModalVisible)
|
|
813
|
+
this.modalError = errorMessage(e);
|
|
814
|
+
else
|
|
815
|
+
this.error = errorMessage(e);
|
|
816
|
+
},
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
QualityParametersComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: QualityParametersComponent, deps: [{ token: QualityApiService }, { token: i2.PermissionService }, { token: i0.ChangeDetectorRef }, { token: i2$1.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Component });
|
|
821
|
+
QualityParametersComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: QualityParametersComponent, selector: "lib-quality-parameters", viewQueries: [{ propertyName: "stepEditor", first: true, predicate: ["stepEditor"], descendants: true }], ngImport: i0, template: "<div class=\"container-fluid\">\r\n <div class=\"mb-2\">\r\n <h3 class=\"page-title\">Kalite Parametreleri (Kalite Sorular\u0131)</h3>\r\n </div>\r\n\r\n <div class=\"card mt-2\"><div class=\"card-body\">\r\n <div class=\"btn-group mb-3\" role=\"tablist\"><button class=\"btn\" [class.btn-primary]=\"controlType === 'Input'\" [class.btn-outline-secondary]=\"controlType !== 'Input'\" (click)=\"switchType('Input')\">Girdi Kontrol</button><button class=\"btn\" [class.btn-primary]=\"controlType === 'Process'\" [class.btn-outline-secondary]=\"controlType !== 'Process'\" (click)=\"switchType('Process')\">Proses Kontrol</button></div>\r\n <div class=\"row mb-3\" *ngIf=\"controlType === 'Input'\">\r\n <div class=\"col-md-6\"><label>Ara\u00E7 Hareket T\u00FCr\u00FC</label><select class=\"form-control\" [(ngModel)]=\"movementTypeCode\" (change)=\"selectInput()\"><option value=\"\">T\u00FCm\u00FC</option><option *ngFor=\"let type of movementTypes\" [value]=\"type.code\">{{ type.name }}</option></select></div>\r\n <div class=\"col-md-6\"><label>Ara\u00E7 Hareket T\u00FCr\u00FC / Detay</label><select class=\"form-control\" [(ngModel)]=\"movementDetailCode\" (change)=\"selectInput()\"><option value=\"\">Se\u00E7in</option><option *ngFor=\"let d of visibleDetails\" [value]=\"d.code\">{{ d.name || d.movementTypeCode }}{{ d.detailCode ? ' / ' + d.detailCode : ' (detays\u0131z)' }}</option></select></div>\r\n <p class=\"col-md-12 mt-2 text-muted\" *ngIf=\"!visibleDetails.length\">\u00D6nce Kalite Tan\u0131mlar\u0131 ekran\u0131nda kalite kontrole tabi hareket t\u00FCr\u00FCn\u00FC tan\u0131mlay\u0131n.</p>\r\n </div>\r\n <div class=\"row align-items-end mb-3\">\r\n <div class=\"col-md-4\" *ngIf=\"controlType === 'Process'\">\r\n <label for=\"formSelect\">Form</label>\r\n <select id=\"formSelect\" class=\"form-control\" [disabled]=\"busy\" [(ngModel)]=\"formCode\" (change)=\"load()\">\r\n <option *ngFor=\"let form of visibleForms\" [value]=\"form.code\">{{ form.documentCode }} \u2013 {{ form.name }}</option>\r\n </select>\r\n </div>\r\n <div class=\"col-md-8 text-md-right mt-2 mt-md-0\">\r\n <button class=\"btn btn-primary\" *ngIf=\"canCreate\" (click)=\"addParameter()\" [disabled]=\"busy || !template || newInputForm\">+ Yeni Parametre</button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"error\" class=\"alert alert-danger\">{{ error }}</div>\r\n <div *ngIf=\"success\" class=\"alert alert-success\" (click)=\"success = ''\">{{ success }}</div>\r\n <div class=\"quality-grid-loading\" *ngIf=\"busy\" role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\r\n <span class=\"spinner-border text-primary\" aria-hidden=\"true\"></span>\r\n <span>{{ busyText }}</span>\r\n </div>\r\n\r\n <ng-container *ngIf=\"template\">\r\n <div [hidden]=\"busy\">\r\n <div class=\"row align-items-end mb-3\" *ngIf=\"controlType === 'Process'\">\r\n <div class=\"col-md-4\"><label for=\"facilitySelect\">Proses s\u0131ras\u0131 i\u00E7in tesis</label>\r\n <select id=\"facilitySelect\" class=\"form-control\" [(ngModel)]=\"facilityCode\" (change)=\"loadSteps()\">\r\n <option *ngFor=\"let facility of matchingFacilities()\" [value]=\"facility.code\">{{ facility.name }}</option>\r\n </select>\r\n </div>\r\n <div class=\"col-md-8 text-md-right\"><button class=\"btn btn-outline-primary\" *ngIf=\"canEdit\" (click)=\"addStep()\">+ Proses Ad\u0131m\u0131</button></div>\r\n </div>\r\n <div class=\"mb-3\" *ngIf=\"controlType === 'Process'\">\r\n <span class=\"step-pill\" *ngFor=\"let step of facilitySteps\">\r\n <button type=\"button\" class=\"btn btn-sm\" [class.btn-outline-primary]=\"step.active\" [class.btn-outline-secondary]=\"!step.active\"\r\n (click)=\"editStep(step)\" [disabled]=\"!canEdit\">{{ step.order }}. {{ step.name }}<span *ngIf=\"!step.active\"> (pasif)</span></button>\r\n </span>\r\n </div>\r\n <div #stepEditor tabindex=\"-1\" class=\"card mt-3 mb-3 editor-card\" *ngIf=\"editingStep as step\"><div class=\"card-body\">\r\n <h5>{{ newStep ? 'Yeni Proses Ad\u0131m\u0131' : 'Proses Ad\u0131m\u0131n\u0131 D\u00FCzenle' }}</h5>\r\n <div class=\"row\">\r\n <div class=\"col-md-2\"><label>Kod</label><input class=\"form-control\" [(ngModel)]=\"step.code\" [disabled]=\"!newStep\" /></div>\r\n <div class=\"col-md-2\"><label>Proses Kodu</label><input class=\"form-control\" [(ngModel)]=\"step.processCode\" [disabled]=\"!newStep\" /></div>\r\n <div class=\"col-md-4\"><label>Ad</label><input class=\"form-control\" [(ngModel)]=\"step.name\" /></div>\r\n <div class=\"col-md-2\"><label>S\u0131ra</label><input type=\"number\" min=\"1\" class=\"form-control\" [(ngModel)]=\"step.order\" /></div>\r\n <div class=\"col-md-2 d-flex align-items-end\"><label><input type=\"checkbox\" [(ngModel)]=\"step.active\" /> Aktif</label></div>\r\n </div>\r\n <button class=\"btn btn-primary mt-3 mr-2\" (click)=\"saveStep()\" [disabled]=\"busy\">Kaydet</button>\r\n <button class=\"btn btn-secondary mt-3\" (click)=\"editingStep = null\">\u0130ptal</button>\r\n </div></div>\r\n <div class=\"form-header rounded p-3 mb-3\">\r\n <p *ngIf=\"newInputForm\" class=\"text-muted\">\u00D6nce form ba\u015Fl\u0131\u011F\u0131n\u0131 kaydedin, ard\u0131ndan kalite sorular\u0131n\u0131 ekleyin.</p>\r\n <div class=\"row\">\r\n <div class=\"col-md-4\"><label>Form Ad\u0131</label><input class=\"form-control\" [(ngModel)]=\"template.form.name\" [disabled]=\"!canEdit\" /></div>\r\n <div class=\"col-md-2\"><label>Dok\u00FCman Kodu</label><input class=\"form-control\" [(ngModel)]=\"template.form.documentCode\" [disabled]=\"!canEdit\" /></div>\r\n <div class=\"col-md-2\"><label>Yay\u0131n Tarihi</label><input type=\"date\" class=\"form-control\" [(ngModel)]=\"template.form.publicationDate\" [disabled]=\"!canEdit\" /></div>\r\n <div class=\"col-md-2\"><label>Revizyon Tarihi</label><input type=\"date\" class=\"form-control\" [(ngModel)]=\"template.form.revisionDate\" [disabled]=\"!canEdit\" /></div>\r\n <div class=\"col-md-2\"><label>Revizyon No</label><input class=\"form-control\" [(ngModel)]=\"template.form.revisionNumber\" [disabled]=\"!canEdit\" /></div>\r\n </div>\r\n <div class=\"row mt-2\" *ngIf=\"controlType === 'Input'\"><div class=\"col-md-4\"><label>Ortalama Tipi</label><select class=\"form-control\" [(ngModel)]=\"template.form.averageMode\" [disabled]=\"!canEdit\"><option value=\"Arithmetic\">Aritmetik</option><option value=\"Weighted\">Miktar a\u011F\u0131rl\u0131kl\u0131</option></select></div><div class=\"col-md-4\"><label>Miktar Birimi</label><select class=\"form-control\" [(ngModel)]=\"template.form.quantityUnit\" [disabled]=\"!canEdit\"><option value=\"kg\">Kilogram</option><option value=\"t\">Ton</option></select></div></div>\r\n <button class=\"btn btn-outline-primary mt-3\" *ngIf=\"canEdit\" (click)=\"editForm()\" [disabled]=\"busy\">Ba\u015Fl\u0131\u011F\u0131 Kaydet</button>\r\n </div>\r\n\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-bordered table-striped table-sm parameter-table\">\r\n <thead><tr><th>\u0130\u015Flemler</th><th *ngIf=\"controlType === 'Process'\">Proses Ad\u0131m\u0131</th><th>S\u0131ra</th><th>Kod</th><th>Parametre / Soru</th><th>Birim</th><th>Veri Tipi</th><th>Limit / Nominal</th><th>Durum</th></tr></thead>\r\n <tbody>\r\n <tr *ngFor=\"let parameter of orderedParameters()\">\r\n <td class=\"actions\">\r\n <button class=\"btn btn-sm btn-outline-primary mr-1\" *ngIf=\"canEdit\" (click)=\"editParameter(parameter)\">D\u00FCzenle</button>\r\n <button class=\"btn btn-sm btn-outline-secondary mr-1\" *ngIf=\"canCreate\" (click)=\"addLimit(parameter)\">+ Limit</button>\r\n <button class=\"btn btn-sm btn-outline-danger\" *ngIf=\"canDelete && parameter.active\" (click)=\"deleteParameter(parameter)\">Sil</button>\r\n </td>\r\n <td *ngIf=\"controlType === 'Process'\">{{ processName(parameter.stepCode) }}</td><td>{{ parameter.order }}</td>\r\n <td><code>{{ parameter.code }}</code></td><td>{{ parameter.name }}</td><td>{{ parameter.unit || '\u2014' }}</td>\r\n <td>{{ parameter.valueType }}<span *ngIf=\"parameter.calculated\"> / Hesaplanan</span></td>\r\n <td>\r\n <div *ngFor=\"let limit of limitsFor(parameter.code)\">\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0 limit-link\" (click)=\"editLimit(limit)\">{{ limit.code }}</button>:\r\n <span *ngIf=\"limit.oilType\">{{ limit.oilType }} \u00B7 </span>\r\n <span *ngIf=\"limit.origin\">{{ limit.origin === 'Imported' ? '\u0130thal' : '\u0130\u00E7 Piyasa' }} \u00B7 </span>\r\n <span *ngIf=\"limit.minimum != null\">Min {{ limit.minimum }} </span>\r\n <span *ngIf=\"limit.maximum != null\">Max {{ limit.maximum }} </span>\r\n <span *ngIf=\"limit.nominal != null\">Nominal {{ limit.nominal }} </span>\r\n <span *ngIf=\"limit.expectedText\">{{ limit.expectedText }}</span>\r\n <span *ngIf=\"!limit.active\" class=\"text-muted\">(pasif)</span>\r\n </div>\r\n </td>\r\n <td>{{ parameter.active ? 'Aktif' : 'Pasif' }}</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n </div>\r\n </ng-container>\r\n </div></div>\r\n</div>\r\n\r\n<abp-modal [visible]=\"parameterModalVisible\" (visibleChange)=\"parameterModalChanged($event)\"\r\n [busy]=\"busy\" [options]=\"editorModalOptions\" [suppressUnsavedChangesWarning]=\"true\">\r\n <ng-template #abpHeader>\r\n <h5 class=\"modal-title\">{{ newParameter ? 'Yeni Parametre' : 'Parametreyi D\u00FCzenle' }}</h5>\r\n </ng-template>\r\n <ng-template #abpBody>\r\n <div *ngIf=\"modalError\" class=\"alert alert-danger\" role=\"alert\">{{ modalError }}</div>\r\n <div *ngIf=\"busy\" class=\"d-flex align-items-center mb-3\" role=\"status\" aria-live=\"polite\">\r\n <span class=\"spinner-border spinner-border-sm text-primary mr-2\" aria-hidden=\"true\"></span>\r\n <span>{{ busyText }}</span>\r\n </div>\r\n <fieldset *ngIf=\"editingParameter as parameter\" [disabled]=\"busy\" class=\"border-0 p-0 m-0\">\r\n <div class=\"row\">\r\n <div class=\"col-md-4\"><label>Kod</label><input class=\"form-control\" [(ngModel)]=\"parameter.code\" [disabled]=\"!newParameter\" /></div>\r\n <div class=\"col-md-4\"><label>Ad / Soru</label><input class=\"form-control\" [(ngModel)]=\"parameter.name\" /></div>\r\n <div class=\"col-md-4\" *ngIf=\"controlType === 'Process'\"><label>Proses Ad\u0131m\u0131</label><select class=\"form-control\" [(ngModel)]=\"parameter.stepCode\"><option *ngFor=\"let step of steps()\" [value]=\"step.processCode\">{{ step.name }}</option></select></div>\r\n <div class=\"col-md-4\"><label>S\u0131ra</label><input type=\"number\" class=\"form-control\" [(ngModel)]=\"parameter.order\" /></div>\r\n <div class=\"col-md-4\"><label>Birim</label><input class=\"form-control\" [(ngModel)]=\"parameter.unit\" /></div>\r\n <div class=\"col-md-4\"><label>Veri Tipi</label><select class=\"form-control\" [(ngModel)]=\"parameter.valueType\"><option value=\"Number\">Say\u0131sal</option><option value=\"Text\">Metin</option><option value=\"Choice\">Se\u00E7im</option></select></div>\r\n </div>\r\n <div class=\"row mt-2\">\r\n <div class=\"col-md-4\"><label>Ondal\u0131k Basamak</label><input type=\"number\" min=\"0\" max=\"8\" class=\"form-control\" [(ngModel)]=\"parameter.decimalPlaces\" /></div>\r\n <div class=\"col-md-4\"><label>Se\u00E7enekler (virg\u00FClle ayr\u0131lm\u0131\u015F)</label><input class=\"form-control\" [(ngModel)]=\"optionsText\" [disabled]=\"parameter.valueType !== 'Choice'\" /></div>\r\n <div class=\"col-md-4\"><label>Hesaplama Form\u00FCl\u00FC</label><input class=\"form-control\" [(ngModel)]=\"parameter.formula\" [disabled]=\"!parameter.calculated\" placeholder=\"PARAM_KODU * 2\" /></div>\r\n <div class=\"col-md-4 d-flex flex-column justify-content-end\"><label><input type=\"checkbox\" [(ngModel)]=\"parameter.required\" /> Zorunlu</label><label><input type=\"checkbox\" [(ngModel)]=\"parameter.calculated\" /> Hesaplanan</label><label><input type=\"checkbox\" [(ngModel)]=\"parameter.active\" /> Aktif</label></div>\r\n </div>\r\n </fieldset>\r\n </ng-template>\r\n <ng-template #abpFooter>\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"closeParameterModal()\" [disabled]=\"busy\">\u0130ptal</button>\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"saveParameter()\" [disabled]=\"busy\">Kaydet</button>\r\n </ng-template>\r\n</abp-modal>\r\n\r\n<abp-modal [visible]=\"limitModalVisible\" (visibleChange)=\"limitModalChanged($event)\"\r\n [busy]=\"busy\" [options]=\"editorModalOptions\" [suppressUnsavedChangesWarning]=\"true\">\r\n <ng-template #abpHeader>\r\n <h5 class=\"modal-title\">{{ newLimit ? 'Yeni Limit' : 'Limiti D\u00FCzenle' }} \u2013 {{ editingLimit?.parameterCode }}</h5>\r\n </ng-template>\r\n <ng-template #abpBody>\r\n <div *ngIf=\"modalError\" class=\"alert alert-danger\" role=\"alert\">{{ modalError }}</div>\r\n <div *ngIf=\"busy\" class=\"d-flex align-items-center mb-3\" role=\"status\" aria-live=\"polite\">\r\n <span class=\"spinner-border spinner-border-sm text-primary mr-2\" aria-hidden=\"true\"></span>\r\n <span>{{ busyText }}</span>\r\n </div>\r\n <fieldset *ngIf=\"editingLimit as limit\" [disabled]=\"busy\" class=\"border-0 p-0 m-0\">\r\n <div class=\"row\">\r\n <div class=\"col-md-4\"><label>Kod</label><input class=\"form-control\" [(ngModel)]=\"limit.code\" [disabled]=\"!newLimit\" /></div>\r\n <div class=\"col-md-4\"><label>Ya\u011F Cinsi / Ko\u015Ful</label><select class=\"form-control\" [(ngModel)]=\"limit.oilType\"><option value=\"\">T\u00FCm\u00FC</option><option value=\"Palm Oil\">Palm Oil</option><option value=\"Palm Olein\">Palm Olein</option></select></div>\r\n <div class=\"col-md-4\"><label>Men\u015Fei</label><select class=\"form-control\" [(ngModel)]=\"limit.origin\"><option value=\"\">T\u00FCm\u00FC</option><option value=\"Domestic\">\u0130\u00E7 Piyasa</option><option value=\"Imported\">\u0130thal</option></select></div>\r\n <div class=\"col-md-4\"><label>Min</label><input type=\"number\" class=\"form-control\" [(ngModel)]=\"limit.minimum\" /></div>\r\n <div class=\"col-md-4\"><label>Max</label><input type=\"number\" class=\"form-control\" [(ngModel)]=\"limit.maximum\" /></div>\r\n <div class=\"col-md-4\"><label>Nominal</label><input type=\"number\" class=\"form-control\" [(ngModel)]=\"limit.nominal\" /></div>\r\n <div class=\"col-md-4\"><label>Beklenen Metin</label><input class=\"form-control\" [(ngModel)]=\"limit.expectedText\" /></div>\r\n </div>\r\n <div class=\"row mt-2\">\r\n <div class=\"col-md-4\"><label>Ba\u015Flang\u0131\u00E7</label><input type=\"date\" class=\"form-control\" [(ngModel)]=\"limit.validFrom\" /></div>\r\n <div class=\"col-md-4\"><label>Biti\u015F</label><input type=\"date\" class=\"form-control\" [(ngModel)]=\"limit.validUntil\" /></div>\r\n <div class=\"col-md-4 d-flex align-items-end\"><label><input type=\"checkbox\" [(ngModel)]=\"limit.active\" /> Aktif</label></div>\r\n </div>\r\n </fieldset>\r\n </ng-template>\r\n <ng-template #abpFooter>\r\n <button type=\"button\" class=\"btn btn-outline-danger\" *ngIf=\"!newLimit && canDelete\"\r\n (click)=\"deleteLimit(editingLimit!)\" [disabled]=\"busy\">Sil</button>\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"closeLimitModal()\" [disabled]=\"busy\">\u0130ptal</button>\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"saveLimit()\" [disabled]=\"busy\">Kaydet</button>\r\n </ng-template>\r\n</abp-modal>\r\n", styles: [".form-header{background:#f7f8fa;border:1px solid #e3e6eb}.parameter-table{min-width:1100px}.parameter-table .actions{white-space:nowrap}.parameter-table .limit-link{color:#007bff}.parameter-table .limit-link:hover,.parameter-table .limit-link:focus{color:#0056b3}.editor-card{border-color:#8864ac;scroll-margin-top:90px}.editor-card:focus{outline:2px solid #8864ac;outline-offset:2px}.step-pill{display:inline-block;margin:0 .4rem .4rem 0}.quality-grid-loading{min-height:280px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;background:#f8f9fa;border:1px solid #dee2e6;border-radius:4px;color:#495057}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.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: i5.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i5.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i5.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i6.ModalComponent, selector: "abp-modal", inputs: ["visible", "busy", "options", "suppressUnsavedChangesWarning"], outputs: ["visibleChange", "init", "appear", "disappear"] }] });
|
|
822
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: QualityParametersComponent, decorators: [{
|
|
823
|
+
type: Component,
|
|
824
|
+
args: [{ selector: 'lib-quality-parameters', template: "<div class=\"container-fluid\">\r\n <div class=\"mb-2\">\r\n <h3 class=\"page-title\">Kalite Parametreleri (Kalite Sorular\u0131)</h3>\r\n </div>\r\n\r\n <div class=\"card mt-2\"><div class=\"card-body\">\r\n <div class=\"btn-group mb-3\" role=\"tablist\"><button class=\"btn\" [class.btn-primary]=\"controlType === 'Input'\" [class.btn-outline-secondary]=\"controlType !== 'Input'\" (click)=\"switchType('Input')\">Girdi Kontrol</button><button class=\"btn\" [class.btn-primary]=\"controlType === 'Process'\" [class.btn-outline-secondary]=\"controlType !== 'Process'\" (click)=\"switchType('Process')\">Proses Kontrol</button></div>\r\n <div class=\"row mb-3\" *ngIf=\"controlType === 'Input'\">\r\n <div class=\"col-md-6\"><label>Ara\u00E7 Hareket T\u00FCr\u00FC</label><select class=\"form-control\" [(ngModel)]=\"movementTypeCode\" (change)=\"selectInput()\"><option value=\"\">T\u00FCm\u00FC</option><option *ngFor=\"let type of movementTypes\" [value]=\"type.code\">{{ type.name }}</option></select></div>\r\n <div class=\"col-md-6\"><label>Ara\u00E7 Hareket T\u00FCr\u00FC / Detay</label><select class=\"form-control\" [(ngModel)]=\"movementDetailCode\" (change)=\"selectInput()\"><option value=\"\">Se\u00E7in</option><option *ngFor=\"let d of visibleDetails\" [value]=\"d.code\">{{ d.name || d.movementTypeCode }}{{ d.detailCode ? ' / ' + d.detailCode : ' (detays\u0131z)' }}</option></select></div>\r\n <p class=\"col-md-12 mt-2 text-muted\" *ngIf=\"!visibleDetails.length\">\u00D6nce Kalite Tan\u0131mlar\u0131 ekran\u0131nda kalite kontrole tabi hareket t\u00FCr\u00FCn\u00FC tan\u0131mlay\u0131n.</p>\r\n </div>\r\n <div class=\"row align-items-end mb-3\">\r\n <div class=\"col-md-4\" *ngIf=\"controlType === 'Process'\">\r\n <label for=\"formSelect\">Form</label>\r\n <select id=\"formSelect\" class=\"form-control\" [disabled]=\"busy\" [(ngModel)]=\"formCode\" (change)=\"load()\">\r\n <option *ngFor=\"let form of visibleForms\" [value]=\"form.code\">{{ form.documentCode }} \u2013 {{ form.name }}</option>\r\n </select>\r\n </div>\r\n <div class=\"col-md-8 text-md-right mt-2 mt-md-0\">\r\n <button class=\"btn btn-primary\" *ngIf=\"canCreate\" (click)=\"addParameter()\" [disabled]=\"busy || !template || newInputForm\">+ Yeni Parametre</button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"error\" class=\"alert alert-danger\">{{ error }}</div>\r\n <div *ngIf=\"success\" class=\"alert alert-success\" (click)=\"success = ''\">{{ success }}</div>\r\n <div class=\"quality-grid-loading\" *ngIf=\"busy\" role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\r\n <span class=\"spinner-border text-primary\" aria-hidden=\"true\"></span>\r\n <span>{{ busyText }}</span>\r\n </div>\r\n\r\n <ng-container *ngIf=\"template\">\r\n <div [hidden]=\"busy\">\r\n <div class=\"row align-items-end mb-3\" *ngIf=\"controlType === 'Process'\">\r\n <div class=\"col-md-4\"><label for=\"facilitySelect\">Proses s\u0131ras\u0131 i\u00E7in tesis</label>\r\n <select id=\"facilitySelect\" class=\"form-control\" [(ngModel)]=\"facilityCode\" (change)=\"loadSteps()\">\r\n <option *ngFor=\"let facility of matchingFacilities()\" [value]=\"facility.code\">{{ facility.name }}</option>\r\n </select>\r\n </div>\r\n <div class=\"col-md-8 text-md-right\"><button class=\"btn btn-outline-primary\" *ngIf=\"canEdit\" (click)=\"addStep()\">+ Proses Ad\u0131m\u0131</button></div>\r\n </div>\r\n <div class=\"mb-3\" *ngIf=\"controlType === 'Process'\">\r\n <span class=\"step-pill\" *ngFor=\"let step of facilitySteps\">\r\n <button type=\"button\" class=\"btn btn-sm\" [class.btn-outline-primary]=\"step.active\" [class.btn-outline-secondary]=\"!step.active\"\r\n (click)=\"editStep(step)\" [disabled]=\"!canEdit\">{{ step.order }}. {{ step.name }}<span *ngIf=\"!step.active\"> (pasif)</span></button>\r\n </span>\r\n </div>\r\n <div #stepEditor tabindex=\"-1\" class=\"card mt-3 mb-3 editor-card\" *ngIf=\"editingStep as step\"><div class=\"card-body\">\r\n <h5>{{ newStep ? 'Yeni Proses Ad\u0131m\u0131' : 'Proses Ad\u0131m\u0131n\u0131 D\u00FCzenle' }}</h5>\r\n <div class=\"row\">\r\n <div class=\"col-md-2\"><label>Kod</label><input class=\"form-control\" [(ngModel)]=\"step.code\" [disabled]=\"!newStep\" /></div>\r\n <div class=\"col-md-2\"><label>Proses Kodu</label><input class=\"form-control\" [(ngModel)]=\"step.processCode\" [disabled]=\"!newStep\" /></div>\r\n <div class=\"col-md-4\"><label>Ad</label><input class=\"form-control\" [(ngModel)]=\"step.name\" /></div>\r\n <div class=\"col-md-2\"><label>S\u0131ra</label><input type=\"number\" min=\"1\" class=\"form-control\" [(ngModel)]=\"step.order\" /></div>\r\n <div class=\"col-md-2 d-flex align-items-end\"><label><input type=\"checkbox\" [(ngModel)]=\"step.active\" /> Aktif</label></div>\r\n </div>\r\n <button class=\"btn btn-primary mt-3 mr-2\" (click)=\"saveStep()\" [disabled]=\"busy\">Kaydet</button>\r\n <button class=\"btn btn-secondary mt-3\" (click)=\"editingStep = null\">\u0130ptal</button>\r\n </div></div>\r\n <div class=\"form-header rounded p-3 mb-3\">\r\n <p *ngIf=\"newInputForm\" class=\"text-muted\">\u00D6nce form ba\u015Fl\u0131\u011F\u0131n\u0131 kaydedin, ard\u0131ndan kalite sorular\u0131n\u0131 ekleyin.</p>\r\n <div class=\"row\">\r\n <div class=\"col-md-4\"><label>Form Ad\u0131</label><input class=\"form-control\" [(ngModel)]=\"template.form.name\" [disabled]=\"!canEdit\" /></div>\r\n <div class=\"col-md-2\"><label>Dok\u00FCman Kodu</label><input class=\"form-control\" [(ngModel)]=\"template.form.documentCode\" [disabled]=\"!canEdit\" /></div>\r\n <div class=\"col-md-2\"><label>Yay\u0131n Tarihi</label><input type=\"date\" class=\"form-control\" [(ngModel)]=\"template.form.publicationDate\" [disabled]=\"!canEdit\" /></div>\r\n <div class=\"col-md-2\"><label>Revizyon Tarihi</label><input type=\"date\" class=\"form-control\" [(ngModel)]=\"template.form.revisionDate\" [disabled]=\"!canEdit\" /></div>\r\n <div class=\"col-md-2\"><label>Revizyon No</label><input class=\"form-control\" [(ngModel)]=\"template.form.revisionNumber\" [disabled]=\"!canEdit\" /></div>\r\n </div>\r\n <div class=\"row mt-2\" *ngIf=\"controlType === 'Input'\"><div class=\"col-md-4\"><label>Ortalama Tipi</label><select class=\"form-control\" [(ngModel)]=\"template.form.averageMode\" [disabled]=\"!canEdit\"><option value=\"Arithmetic\">Aritmetik</option><option value=\"Weighted\">Miktar a\u011F\u0131rl\u0131kl\u0131</option></select></div><div class=\"col-md-4\"><label>Miktar Birimi</label><select class=\"form-control\" [(ngModel)]=\"template.form.quantityUnit\" [disabled]=\"!canEdit\"><option value=\"kg\">Kilogram</option><option value=\"t\">Ton</option></select></div></div>\r\n <button class=\"btn btn-outline-primary mt-3\" *ngIf=\"canEdit\" (click)=\"editForm()\" [disabled]=\"busy\">Ba\u015Fl\u0131\u011F\u0131 Kaydet</button>\r\n </div>\r\n\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-bordered table-striped table-sm parameter-table\">\r\n <thead><tr><th>\u0130\u015Flemler</th><th *ngIf=\"controlType === 'Process'\">Proses Ad\u0131m\u0131</th><th>S\u0131ra</th><th>Kod</th><th>Parametre / Soru</th><th>Birim</th><th>Veri Tipi</th><th>Limit / Nominal</th><th>Durum</th></tr></thead>\r\n <tbody>\r\n <tr *ngFor=\"let parameter of orderedParameters()\">\r\n <td class=\"actions\">\r\n <button class=\"btn btn-sm btn-outline-primary mr-1\" *ngIf=\"canEdit\" (click)=\"editParameter(parameter)\">D\u00FCzenle</button>\r\n <button class=\"btn btn-sm btn-outline-secondary mr-1\" *ngIf=\"canCreate\" (click)=\"addLimit(parameter)\">+ Limit</button>\r\n <button class=\"btn btn-sm btn-outline-danger\" *ngIf=\"canDelete && parameter.active\" (click)=\"deleteParameter(parameter)\">Sil</button>\r\n </td>\r\n <td *ngIf=\"controlType === 'Process'\">{{ processName(parameter.stepCode) }}</td><td>{{ parameter.order }}</td>\r\n <td><code>{{ parameter.code }}</code></td><td>{{ parameter.name }}</td><td>{{ parameter.unit || '\u2014' }}</td>\r\n <td>{{ parameter.valueType }}<span *ngIf=\"parameter.calculated\"> / Hesaplanan</span></td>\r\n <td>\r\n <div *ngFor=\"let limit of limitsFor(parameter.code)\">\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0 limit-link\" (click)=\"editLimit(limit)\">{{ limit.code }}</button>:\r\n <span *ngIf=\"limit.oilType\">{{ limit.oilType }} \u00B7 </span>\r\n <span *ngIf=\"limit.origin\">{{ limit.origin === 'Imported' ? '\u0130thal' : '\u0130\u00E7 Piyasa' }} \u00B7 </span>\r\n <span *ngIf=\"limit.minimum != null\">Min {{ limit.minimum }} </span>\r\n <span *ngIf=\"limit.maximum != null\">Max {{ limit.maximum }} </span>\r\n <span *ngIf=\"limit.nominal != null\">Nominal {{ limit.nominal }} </span>\r\n <span *ngIf=\"limit.expectedText\">{{ limit.expectedText }}</span>\r\n <span *ngIf=\"!limit.active\" class=\"text-muted\">(pasif)</span>\r\n </div>\r\n </td>\r\n <td>{{ parameter.active ? 'Aktif' : 'Pasif' }}</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n </div>\r\n </ng-container>\r\n </div></div>\r\n</div>\r\n\r\n<abp-modal [visible]=\"parameterModalVisible\" (visibleChange)=\"parameterModalChanged($event)\"\r\n [busy]=\"busy\" [options]=\"editorModalOptions\" [suppressUnsavedChangesWarning]=\"true\">\r\n <ng-template #abpHeader>\r\n <h5 class=\"modal-title\">{{ newParameter ? 'Yeni Parametre' : 'Parametreyi D\u00FCzenle' }}</h5>\r\n </ng-template>\r\n <ng-template #abpBody>\r\n <div *ngIf=\"modalError\" class=\"alert alert-danger\" role=\"alert\">{{ modalError }}</div>\r\n <div *ngIf=\"busy\" class=\"d-flex align-items-center mb-3\" role=\"status\" aria-live=\"polite\">\r\n <span class=\"spinner-border spinner-border-sm text-primary mr-2\" aria-hidden=\"true\"></span>\r\n <span>{{ busyText }}</span>\r\n </div>\r\n <fieldset *ngIf=\"editingParameter as parameter\" [disabled]=\"busy\" class=\"border-0 p-0 m-0\">\r\n <div class=\"row\">\r\n <div class=\"col-md-4\"><label>Kod</label><input class=\"form-control\" [(ngModel)]=\"parameter.code\" [disabled]=\"!newParameter\" /></div>\r\n <div class=\"col-md-4\"><label>Ad / Soru</label><input class=\"form-control\" [(ngModel)]=\"parameter.name\" /></div>\r\n <div class=\"col-md-4\" *ngIf=\"controlType === 'Process'\"><label>Proses Ad\u0131m\u0131</label><select class=\"form-control\" [(ngModel)]=\"parameter.stepCode\"><option *ngFor=\"let step of steps()\" [value]=\"step.processCode\">{{ step.name }}</option></select></div>\r\n <div class=\"col-md-4\"><label>S\u0131ra</label><input type=\"number\" class=\"form-control\" [(ngModel)]=\"parameter.order\" /></div>\r\n <div class=\"col-md-4\"><label>Birim</label><input class=\"form-control\" [(ngModel)]=\"parameter.unit\" /></div>\r\n <div class=\"col-md-4\"><label>Veri Tipi</label><select class=\"form-control\" [(ngModel)]=\"parameter.valueType\"><option value=\"Number\">Say\u0131sal</option><option value=\"Text\">Metin</option><option value=\"Choice\">Se\u00E7im</option></select></div>\r\n </div>\r\n <div class=\"row mt-2\">\r\n <div class=\"col-md-4\"><label>Ondal\u0131k Basamak</label><input type=\"number\" min=\"0\" max=\"8\" class=\"form-control\" [(ngModel)]=\"parameter.decimalPlaces\" /></div>\r\n <div class=\"col-md-4\"><label>Se\u00E7enekler (virg\u00FClle ayr\u0131lm\u0131\u015F)</label><input class=\"form-control\" [(ngModel)]=\"optionsText\" [disabled]=\"parameter.valueType !== 'Choice'\" /></div>\r\n <div class=\"col-md-4\"><label>Hesaplama Form\u00FCl\u00FC</label><input class=\"form-control\" [(ngModel)]=\"parameter.formula\" [disabled]=\"!parameter.calculated\" placeholder=\"PARAM_KODU * 2\" /></div>\r\n <div class=\"col-md-4 d-flex flex-column justify-content-end\"><label><input type=\"checkbox\" [(ngModel)]=\"parameter.required\" /> Zorunlu</label><label><input type=\"checkbox\" [(ngModel)]=\"parameter.calculated\" /> Hesaplanan</label><label><input type=\"checkbox\" [(ngModel)]=\"parameter.active\" /> Aktif</label></div>\r\n </div>\r\n </fieldset>\r\n </ng-template>\r\n <ng-template #abpFooter>\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"closeParameterModal()\" [disabled]=\"busy\">\u0130ptal</button>\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"saveParameter()\" [disabled]=\"busy\">Kaydet</button>\r\n </ng-template>\r\n</abp-modal>\r\n\r\n<abp-modal [visible]=\"limitModalVisible\" (visibleChange)=\"limitModalChanged($event)\"\r\n [busy]=\"busy\" [options]=\"editorModalOptions\" [suppressUnsavedChangesWarning]=\"true\">\r\n <ng-template #abpHeader>\r\n <h5 class=\"modal-title\">{{ newLimit ? 'Yeni Limit' : 'Limiti D\u00FCzenle' }} \u2013 {{ editingLimit?.parameterCode }}</h5>\r\n </ng-template>\r\n <ng-template #abpBody>\r\n <div *ngIf=\"modalError\" class=\"alert alert-danger\" role=\"alert\">{{ modalError }}</div>\r\n <div *ngIf=\"busy\" class=\"d-flex align-items-center mb-3\" role=\"status\" aria-live=\"polite\">\r\n <span class=\"spinner-border spinner-border-sm text-primary mr-2\" aria-hidden=\"true\"></span>\r\n <span>{{ busyText }}</span>\r\n </div>\r\n <fieldset *ngIf=\"editingLimit as limit\" [disabled]=\"busy\" class=\"border-0 p-0 m-0\">\r\n <div class=\"row\">\r\n <div class=\"col-md-4\"><label>Kod</label><input class=\"form-control\" [(ngModel)]=\"limit.code\" [disabled]=\"!newLimit\" /></div>\r\n <div class=\"col-md-4\"><label>Ya\u011F Cinsi / Ko\u015Ful</label><select class=\"form-control\" [(ngModel)]=\"limit.oilType\"><option value=\"\">T\u00FCm\u00FC</option><option value=\"Palm Oil\">Palm Oil</option><option value=\"Palm Olein\">Palm Olein</option></select></div>\r\n <div class=\"col-md-4\"><label>Men\u015Fei</label><select class=\"form-control\" [(ngModel)]=\"limit.origin\"><option value=\"\">T\u00FCm\u00FC</option><option value=\"Domestic\">\u0130\u00E7 Piyasa</option><option value=\"Imported\">\u0130thal</option></select></div>\r\n <div class=\"col-md-4\"><label>Min</label><input type=\"number\" class=\"form-control\" [(ngModel)]=\"limit.minimum\" /></div>\r\n <div class=\"col-md-4\"><label>Max</label><input type=\"number\" class=\"form-control\" [(ngModel)]=\"limit.maximum\" /></div>\r\n <div class=\"col-md-4\"><label>Nominal</label><input type=\"number\" class=\"form-control\" [(ngModel)]=\"limit.nominal\" /></div>\r\n <div class=\"col-md-4\"><label>Beklenen Metin</label><input class=\"form-control\" [(ngModel)]=\"limit.expectedText\" /></div>\r\n </div>\r\n <div class=\"row mt-2\">\r\n <div class=\"col-md-4\"><label>Ba\u015Flang\u0131\u00E7</label><input type=\"date\" class=\"form-control\" [(ngModel)]=\"limit.validFrom\" /></div>\r\n <div class=\"col-md-4\"><label>Biti\u015F</label><input type=\"date\" class=\"form-control\" [(ngModel)]=\"limit.validUntil\" /></div>\r\n <div class=\"col-md-4 d-flex align-items-end\"><label><input type=\"checkbox\" [(ngModel)]=\"limit.active\" /> Aktif</label></div>\r\n </div>\r\n </fieldset>\r\n </ng-template>\r\n <ng-template #abpFooter>\r\n <button type=\"button\" class=\"btn btn-outline-danger\" *ngIf=\"!newLimit && canDelete\"\r\n (click)=\"deleteLimit(editingLimit!)\" [disabled]=\"busy\">Sil</button>\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"closeLimitModal()\" [disabled]=\"busy\">\u0130ptal</button>\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"saveLimit()\" [disabled]=\"busy\">Kaydet</button>\r\n </ng-template>\r\n</abp-modal>\r\n", styles: [".form-header{background:#f7f8fa;border:1px solid #e3e6eb}.parameter-table{min-width:1100px}.parameter-table .actions{white-space:nowrap}.parameter-table .limit-link{color:#007bff}.parameter-table .limit-link:hover,.parameter-table .limit-link:focus{color:#0056b3}.editor-card{border-color:#8864ac;scroll-margin-top:90px}.editor-card:focus{outline:2px solid #8864ac;outline-offset:2px}.step-pill{display:inline-block;margin:0 .4rem .4rem 0}.quality-grid-loading{min-height:280px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;background:#f8f9fa;border:1px solid #dee2e6;border-radius:4px;color:#495057}\n"] }]
|
|
825
|
+
}], ctorParameters: function () { return [{ type: QualityApiService }, { type: i2.PermissionService }, { type: i0.ChangeDetectorRef }, { type: i2$1.ActivatedRoute }]; }, propDecorators: { stepEditor: [{
|
|
826
|
+
type: ViewChild,
|
|
827
|
+
args: ['stepEditor']
|
|
828
|
+
}] } });
|
|
829
|
+
|
|
830
|
+
class IntakeListComponent {
|
|
831
|
+
constructor(api, permissions) {
|
|
832
|
+
this.api = api;
|
|
833
|
+
this.permissions = permissions;
|
|
834
|
+
this.statuses = [{ value: 'Waiting', text: 'Bekliyor' }, { value: 'Draft', text: 'Taslak' }, { value: 'Accepted', text: 'Kabul' }, { value: 'Rejected', text: 'Ret' }];
|
|
835
|
+
this.dataSource = new CustomStore({ key: 'docEntry', load: (options) => __awaiter(this, void 0, void 0, function* () {
|
|
836
|
+
this.error = '';
|
|
837
|
+
try {
|
|
838
|
+
const result = yield firstValueFrom(this.api.intakeList(Object.assign(Object.assign({}, this.query), { search: String(options.searchValue || ''), skipCount: options.skip || 0, maxResultCount: options.take || 20, filter: options.filter ? JSON.stringify(options.filter) : '', sort: options.sort ? JSON.stringify(options.sort) : '' })));
|
|
839
|
+
this.rows = result.items;
|
|
840
|
+
this.total = result.totalCount;
|
|
841
|
+
return { data: result.items, totalCount: result.totalCount };
|
|
842
|
+
}
|
|
843
|
+
catch (e) {
|
|
844
|
+
this.error = errorMessage(e);
|
|
845
|
+
throw new Error(this.error);
|
|
846
|
+
}
|
|
847
|
+
}) });
|
|
848
|
+
this.rows = [];
|
|
849
|
+
this.types = [];
|
|
850
|
+
this.total = 0;
|
|
851
|
+
this.busy = false;
|
|
852
|
+
this.error = '';
|
|
853
|
+
this.query = { pendingOnly: true, from: '', until: '', search: '', movementTypeCode: '', status: '', skipCount: 0, maxResultCount: 20 };
|
|
854
|
+
this.cancelRow = null;
|
|
855
|
+
this.reason = '';
|
|
856
|
+
this.statusLabel = statusLabel;
|
|
857
|
+
}
|
|
858
|
+
ngOnInit() { this.api.qualityMovementTypes().subscribe({ next: types => this.types = types, error: e => this.error = errorMessage(e) }); this.load(); }
|
|
859
|
+
allowed(policy) { return this.permissions.getGrantedPolicy('Kalite.Intake.' + policy); }
|
|
860
|
+
editable(row) { return row.vehicleStatus === '0' && !row.firstWeight && !row.hasExited; }
|
|
861
|
+
load(reset = false) {
|
|
862
|
+
var _a, _b;
|
|
863
|
+
this.busy = false;
|
|
864
|
+
if (reset)
|
|
865
|
+
(_a = this.grid) === null || _a === void 0 ? void 0 : _a.instance.pageIndex(0);
|
|
866
|
+
(_b = this.grid) === null || _b === void 0 ? void 0 : _b.instance.refresh();
|
|
867
|
+
}
|
|
868
|
+
tab(pending) { this.query.pendingOnly = pending; this.load(true); }
|
|
869
|
+
page(direction) { this.query.skipCount += direction * this.query.maxResultCount; this.load(); }
|
|
870
|
+
get pageNumber() { return Math.floor(this.query.skipCount / this.query.maxResultCount) + 1; }
|
|
871
|
+
print(row) { this.api.intakePdf(row.docEntry).subscribe({ next: blob => download(blob, `Girdi-Kontrol-${row.docEntry}.pdf`), error: e => this.error = errorMessage(e) }); }
|
|
872
|
+
cancel() {
|
|
873
|
+
if (!this.cancelRow || !this.reason.trim()) {
|
|
874
|
+
this.error = 'İptal gerekçesi girin.';
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
877
|
+
this.busy = true;
|
|
878
|
+
const id = this.cancelRow.docEntry;
|
|
879
|
+
this.api.intake(id).subscribe({ next: form => this.api.cancelIntake(id, form.inspection.revision, this.reason).subscribe({
|
|
880
|
+
next: () => { this.cancelRow = null; this.reason = ''; this.load(); }, error: e => { this.error = errorMessage(e); this.busy = false; }
|
|
881
|
+
}), error: e => { this.error = errorMessage(e); this.busy = false; } });
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
IntakeListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: IntakeListComponent, deps: [{ token: QualityApiService }, { token: i2.PermissionService }], target: i0.ɵɵFactoryTarget.Component });
|
|
885
|
+
IntakeListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: IntakeListComponent, selector: "lib-intake-list", viewQueries: [{ propertyName: "grid", first: true, predicate: ["grid"], descendants: true }], ngImport: i0, template: "<div class=\"container-fluid\"><h3>Ham Ya\u011F Giri\u015F Kalite Kontrol</h3><div class=\"card\"><div class=\"card-body\">\n <div class=\"btn-group mb-3\" role=\"tablist\"><button class=\"btn\" [class.btn-success]=\"query.pendingOnly\" [class.btn-outline-secondary]=\"!query.pendingOnly\" (click)=\"tab(true)\">Kalite Kontrol Bekleyenler</button><button class=\"btn\" [class.btn-success]=\"!query.pendingOnly\" [class.btn-outline-secondary]=\"query.pendingOnly\" (click)=\"tab(false)\">T\u00FCm Kay\u0131tlar</button></div>\n <div class=\"row mb-3\"><div class=\"col-md-3\"><label>Ba\u015Flang\u0131\u00E7</label><input type=\"date\" class=\"form-control\" [(ngModel)]=\"query.from\" /></div><div class=\"col-md-3\"><label>Biti\u015F</label><input type=\"date\" class=\"form-control\" [(ngModel)]=\"query.until\" /></div><div class=\"col-md-3\"><label>Ara\u00E7 Hareket T\u00FCr\u00FC</label><select class=\"form-control\" [(ngModel)]=\"query.movementTypeCode\"><option value=\"\">T\u00FCm\u00FC</option><option *ngFor=\"let type of types\" [value]=\"type.code\">{{type.name}}</option></select></div><div class=\"col-md-3 d-flex align-items-end\"><button class=\"btn btn-primary\" (click)=\"load(true)\">Filtrele</button></div></div>\n <div *ngIf=\"error\" class=\"alert alert-danger\" role=\"alert\">{{error}}</div>\n <dx-data-grid #grid class=\"intake-grid\" [dataSource]=\"dataSource\" [remoteOperations]=\"{paging: true, filtering: true, sorting: true}\" [showBorders]=\"true\" [rowAlternationEnabled]=\"true\" [columnAutoWidth]=\"true\" [allowColumnResizing]=\"true\" columnResizingMode=\"widget\" style=\"height: calc(100vh - 350px)\">\n <dxo-filter-row [visible]=\"true\"></dxo-filter-row><dxo-search-panel [visible]=\"true\" [width]=\"220\" placeholder=\"Ara\u2026\"></dxo-search-panel>\n <dxo-paging [pageSize]=\"20\"></dxo-paging><dxo-pager [visible]=\"true\" [showInfo]=\"true\" [allowedPageSizes]=\"[10,20,50]\" [showPageSizeSelector]=\"true\" [showNavigationButtons]=\"true\"></dxo-pager>\n <dxi-column caption=\"\u0130\u015Flemler\" cellTemplate=\"actions\" [allowFiltering]=\"false\" [allowSorting]=\"false\" [fixed]=\"true\" [width]=\"145\"></dxi-column>\n <dxi-column dataField=\"qualityStatus\" caption=\"Kalite Durumu\" cellTemplate=\"status\"><dxo-lookup [dataSource]=\"statuses\" valueExpr=\"value\" displayExpr=\"text\"></dxo-lookup></dxi-column>\n <dxi-column dataField=\"sequenceNumber\" caption=\"S\u0131ra No\"></dxi-column><dxi-column dataField=\"docNum\" caption=\"Belge No\" dataType=\"number\"></dxi-column><dxi-column dataField=\"gateCode\" caption=\"Kap\u0131\"></dxi-column>\n <dxi-column dataField=\"entryDate\" caption=\"Giri\u015F Tarihi / Saati\" dataType=\"datetime\" format=\"dd.MM.yyyy HH:mm\"></dxi-column><dxi-column dataField=\"movementTypeName\" caption=\"Ara\u00E7 Hareket T\u00FCr\u00FC\"></dxi-column><dxi-column dataField=\"movementDetailName\" caption=\"Detay\"></dxi-column>\n <dxi-column dataField=\"plate\" caption=\"Kamyon Plakas\u0131\"></dxi-column><dxi-column dataField=\"trailerPlate\" caption=\"Dorse Plakas\u0131\"></dxi-column><dxi-column dataField=\"driver\" caption=\"\u015Eof\u00F6r\"></dxi-column>\n <dxi-column dataField=\"partnerName\" caption=\"Muhatap\"></dxi-column><dxi-column dataField=\"shipName\" caption=\"Gemi\"></dxi-column><dxi-column dataField=\"stockTransferNumber\" caption=\"Stok Nakli\"></dxi-column>\n <dxi-column dataField=\"origin\" caption=\"Men\u015Fei\"><dxo-lookup [dataSource]=\"[{code:'Domestic',name:'\u0130\u00E7 Piyasa'},{code:'Imported',name:'\u0130thal'}]\" valueExpr=\"code\" displayExpr=\"name\"></dxo-lookup></dxi-column>\n <dxi-column dataField=\"sealNumber\" caption=\"M\u00FCh\u00FCr No\"></dxi-column><dxi-column dataField=\"analyst\" caption=\"Analizi Yapan\"></dxi-column><dxi-column dataField=\"inspectedAt\" caption=\"Kontrol Tarihi\" dataType=\"datetime\" format=\"dd.MM.yyyy HH:mm\"></dxi-column><dxi-column dataField=\"notes\" caption=\"A\u00E7\u0131klama\"></dxi-column>\n <div *dxTemplate=\"let cell of 'status'\"><span class=\"badge\" [class.badge-success]=\"cell.data.qualityStatus === 'Accepted'\" [class.badge-danger]=\"cell.data.qualityStatus === 'Rejected'\" [class.badge-warning]=\"cell.data.qualityStatus === 'Waiting' || cell.data.qualityStatus === 'Draft'\">{{statusLabel(cell.data.qualityStatus)}}</span></div>\n <div *dxTemplate=\"let cell of 'actions'\" class=\"intake-actions-cell\">\n <div ngbDropdown container=\"body\" class=\"d-inline-block\" placement=\"bottom-start top-start\">\n <button type=\"button\" ngbDropdownToggle class=\"btn btn-sm btn-primary intake-actions-toggle\"><i class=\"fa fa-cog\" aria-hidden=\"true\"></i><span>\u0130\u015Flemler</span></button>\n <div ngbDropdownMenu class=\"intake-action-menu\">\n <a ngbDropdownItem *ngIf=\"editable(cell.data) && allowed('Edit')\" [routerLink]=\"['/kalite/intake',cell.data.docEntry]\">{{cell.data.qualityStatus === 'Waiting' ? 'Kalite Kontrol Yap' : 'D\u00FCzenle'}}</a>\n <a ngbDropdownItem [routerLink]=\"['/kalite/intake',cell.data.docEntry]\" [queryParams]=\"{mode:'view'}\">\u00D6zeti G\u00F6r\u00FCnt\u00FCle</a>\n <button type=\"button\" ngbDropdownItem *ngIf=\"cell.data.qualityStatus !== 'Waiting' && allowed('Print')\" (click)=\"print(cell.data)\">Girdi Kontrol Formu Yazd\u0131r</button>\n <button type=\"button\" ngbDropdownItem *ngIf=\"editable(cell.data) && cell.data.qualityStatus !== 'Waiting' && allowed('Cancel')\" (click)=\"cancelRow = cell.data; reason = ''\">\u0130ptal Et</button>\n </div>\n </div>\n </div>\n </dx-data-grid>\n</div></div></div>\n<abp-modal [visible]=\"!!cancelRow\" (visibleChange)=\"!$event && (cancelRow = null)\" [busy]=\"busy\"><ng-template #abpHeader><h5>Kalite Kontrol\u00FCn\u00FC \u0130ptal Et</h5></ng-template><ng-template #abpBody><label>\u0130ptal Gerek\u00E7esi</label><textarea class=\"form-control\" rows=\"3\" [(ngModel)]=\"reason\"></textarea><p class=\"text-muted mt-2\">Kay\u0131t yeniden kalite kontrol bekleyenlere al\u0131n\u0131r.</p></ng-template><ng-template #abpFooter><button class=\"btn btn-secondary\" (click)=\"cancelRow = null\" [disabled]=\"busy\">Vazge\u00E7</button><button class=\"btn btn-danger\" (click)=\"cancel()\" [disabled]=\"busy || !reason.trim()\">\u0130ptal Et</button></ng-template></abp-modal>\n", styles: [".quality-loading{padding:1.5rem;text-align:center;color:#5b526c}.print-only{display:none}.quality-status{display:inline-flex;align-items:center;gap:.5rem;padding:.55rem .85rem;border:1px solid transparent;border-radius:.4rem;font-size:.9375rem;font-weight:600;line-height:1.4}.quality-status-accepted{color:#166534;background:#dcfce7;border-color:#86efac}.quality-status-rejected{color:#991b1b;background:#fee2e2;border-color:#fca5a5}.quality-status-draft{color:#1e40af;background:#dbeafe;border-color:#93c5fd}.quality-status-waiting{color:#854d0e;background:#fef3c7;border-color:#fcd34d}.vehicle-table{min-width:1950px;white-space:nowrap}.actions{min-width:130px}.quality-questions-link{display:inline-flex;align-items:center;min-height:calc(1.5em + .5rem + 2px);margin-left:.4rem;padding:.25rem .5rem;color:#9a5a00;background:#fff3d6;border:1px solid #edb85b;border-radius:.2rem;font-size:.875rem;line-height:1.5;text-decoration:none}.quality-questions-link:hover,.quality-questions-link:focus{color:#fff;background:#b86b00;border-color:#b86b00;text-decoration:none}.intake-actions-cell{display:flex;align-items:center}:host ::ng-deep .intake-grid .dx-data-row>td{vertical-align:middle}.intake-actions-toggle{display:inline-flex;align-items:center;gap:.5rem;padding:.3rem .65rem;font-family:inherit;font-size:.8125rem;line-height:1.3}.intake-action-menu{min-width:210px;margin-top:.35rem;padding:.3rem;background:#fff;border:1px solid #dee2e6;border-radius:.375rem;box-shadow:0 .25rem .75rem #0000001a}.intake-action-menu .dropdown-item{display:block;text-align:left;border:0;border-radius:.25rem;background:none;color:#343a40;padding:.5rem .65rem;font-family:inherit;font-size:.8125rem;font-weight:400;line-height:1.4;text-decoration:none;white-space:nowrap;cursor:pointer}.intake-action-menu .dropdown-item:hover,.intake-action-menu .dropdown-item:focus-visible{background:#eef2ff;color:#2446b5}.page-size{width:85px}.vehicle-info{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1rem;margin:1rem 0}.vehicle-info label{font-size:.8rem;color:#6c757d;margin-bottom:.2rem}.vehicle-info p{background:#f5f3f8;padding:.55rem;min-height:2.5rem;overflow-wrap:anywhere}.measurement-table{min-width:700px}.measurement-table th{background:#f2edf7}.measurement-table td{vertical-align:middle}.out-of-limit,.rejected-row{background:#ffe6e9!important}.out-of-limit input,.out-of-limit select{border-color:#dc3545}@media (max-width: 900px){.vehicle-info{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width: 550px){.vehicle-info{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.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: i5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2$1.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i6.ModalComponent, selector: "abp-modal", inputs: ["visible", "busy", "options", "suppressUnsavedChangesWarning"], outputs: ["visibleChange", "init", "appear", "disappear"] }, { kind: "component", type: i7.DxDataGridComponent, selector: "dx-data-grid", inputs: ["accessKey", "activeStateEnabled", "allowColumnReordering", "allowColumnResizing", "autoNavigateToFocusedRow", "cacheEnabled", "cellHintEnabled", "columnAutoWidth", "columnChooser", "columnFixing", "columnHidingEnabled", "columnMinWidth", "columnResizingMode", "columns", "columnWidth", "customizeColumns", "dataRowTemplate", "dataSource", "dateSerializationFormat", "disabled", "editing", "elementAttr", "errorRowEnabled", "export", "filterBuilder", "filterBuilderPopup", "filterPanel", "filterRow", "filterSyncEnabled", "filterValue", "focusedColumnIndex", "focusedRowEnabled", "focusedRowIndex", "focusedRowKey", "grouping", "groupPanel", "headerFilter", "height", "highlightChanges", "hint", "hoverStateEnabled", "keyboardNavigation", "keyExpr", "loadPanel", "masterDetail", "noDataText", "pager", "paging", "remoteOperations", "renderAsync", "repaintChangesOnly", "rowAlternationEnabled", "rowDragging", "rowTemplate", "rtlEnabled", "scrolling", "searchPanel", "selectedRowKeys", "selection", "selectionFilter", "showBorders", "showColumnHeaders", "showColumnLines", "showRowLines", "sortByGroupSummaryInfo", "sorting", "stateStoring", "summary", "syncLookupFilterValues", "tabIndex", "toolbar", "twoWayBindingEnabled", "visible", "width", "wordWrapEnabled"], outputs: ["onAdaptiveDetailRowPreparing", "onCellClick", "onCellDblClick", "onCellHoverChanged", "onCellPrepared", "onContentReady", "onContextMenuPreparing", "onDataErrorOccurred", "onDisposing", "onEditCanceled", "onEditCanceling", "onEditingStart", "onEditorPrepared", "onEditorPreparing", "onExporting", "onFocusedCellChanged", "onFocusedCellChanging", "onFocusedRowChanged", "onFocusedRowChanging", "onInitialized", "onInitNewRow", "onKeyDown", "onOptionChanged", "onRowClick", "onRowCollapsed", "onRowCollapsing", "onRowDblClick", "onRowExpanded", "onRowExpanding", "onRowInserted", "onRowInserting", "onRowPrepared", "onRowRemoved", "onRowRemoving", "onRowUpdated", "onRowUpdating", "onRowValidating", "onSaved", "onSaving", "onSelectionChanged", "onToolbarPreparing", "accessKeyChange", "activeStateEnabledChange", "allowColumnReorderingChange", "allowColumnResizingChange", "autoNavigateToFocusedRowChange", "cacheEnabledChange", "cellHintEnabledChange", "columnAutoWidthChange", "columnChooserChange", "columnFixingChange", "columnHidingEnabledChange", "columnMinWidthChange", "columnResizingModeChange", "columnsChange", "columnWidthChange", "customizeColumnsChange", "dataRowTemplateChange", "dataSourceChange", "dateSerializationFormatChange", "disabledChange", "editingChange", "elementAttrChange", "errorRowEnabledChange", "exportChange", "filterBuilderChange", "filterBuilderPopupChange", "filterPanelChange", "filterRowChange", "filterSyncEnabledChange", "filterValueChange", "focusedColumnIndexChange", "focusedRowEnabledChange", "focusedRowIndexChange", "focusedRowKeyChange", "groupingChange", "groupPanelChange", "headerFilterChange", "heightChange", "highlightChangesChange", "hintChange", "hoverStateEnabledChange", "keyboardNavigationChange", "keyExprChange", "loadPanelChange", "masterDetailChange", "noDataTextChange", "pagerChange", "pagingChange", "remoteOperationsChange", "renderAsyncChange", "repaintChangesOnlyChange", "rowAlternationEnabledChange", "rowDraggingChange", "rowTemplateChange", "rtlEnabledChange", "scrollingChange", "searchPanelChange", "selectedRowKeysChange", "selectionChange", "selectionFilterChange", "showBordersChange", "showColumnHeadersChange", "showColumnLinesChange", "showRowLinesChange", "sortByGroupSummaryInfoChange", "sortingChange", "stateStoringChange", "summaryChange", "syncLookupFilterValuesChange", "tabIndexChange", "toolbarChange", "twoWayBindingEnabledChange", "visibleChange", "widthChange", "wordWrapEnabledChange"] }, { kind: "component", type: i8.DxiColumnComponent, selector: "dxi-column", inputs: ["alignment", "allowEditing", "allowExporting", "allowFiltering", "allowFixing", "allowGrouping", "allowHeaderFiltering", "allowHiding", "allowReordering", "allowResizing", "allowSearch", "allowSorting", "autoExpandGroup", "buttons", "calculateCellValue", "calculateDisplayValue", "calculateFilterExpression", "calculateGroupValue", "calculateSortValue", "caption", "cellTemplate", "columns", "cssClass", "customizeText", "dataField", "dataType", "editCellTemplate", "editorOptions", "encodeHtml", "falseText", "filterOperations", "filterType", "filterValue", "filterValues", "fixed", "fixedPosition", "format", "formItem", "groupCellTemplate", "groupIndex", "headerCellTemplate", "headerFilter", "hidingPriority", "isBand", "lookup", "minWidth", "name", "ownerBand", "renderAsync", "selectedFilterOperation", "setCellValue", "showEditorAlways", "showInColumnChooser", "showWhenGrouped", "sortIndex", "sortingMethod", "sortOrder", "trueText", "type", "validationRules", "visible", "visibleIndex", "width"], outputs: ["filterValueChange", "filterValuesChange", "groupIndexChange", "selectedFilterOperationChange", "sortIndexChange", "sortOrderChange", "visibleChange", "visibleIndexChange"] }, { kind: "component", type: i8.DxoLookupComponent, selector: "dxo-lookup", inputs: ["allowClearing", "calculateCellValue", "dataSource", "displayExpr", "valueExpr"] }, { kind: "component", type: i8.DxoFilterRowComponent, selector: "dxo-filter-row", inputs: ["applyFilter", "applyFilterText", "betweenEndText", "betweenStartText", "operationDescriptions", "resetOperationText", "showAllText", "showOperationChooser", "visible"] }, { kind: "component", type: i8.DxoPagerComponent, selector: "dxo-pager", inputs: ["allowedPageSizes", "displayMode", "infoText", "label", "showInfo", "showNavigationButtons", "showPageSizeSelector", "visible"] }, { kind: "component", type: i8.DxoPagingComponent, selector: "dxo-paging", inputs: ["enabled", "pageIndex", "pageSize"], outputs: ["pageIndexChange", "pageSizeChange"] }, { kind: "component", type: i8.DxoSearchPanelComponent, selector: "dxo-search-panel", inputs: ["highlightCaseSensitive", "highlightSearchText", "placeholder", "searchVisibleColumnsOnly", "text", "visible", "width"], outputs: ["textChange"] }, { kind: "directive", type: i9.DxTemplateDirective, selector: "[dxTemplate]", inputs: ["dxTemplateOf"] }, { kind: "directive", type: i10.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { kind: "directive", type: i10.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { kind: "directive", type: i10.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { kind: "directive", type: i10.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["disabled"] }] });
|
|
886
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: IntakeListComponent, decorators: [{
|
|
887
|
+
type: Component,
|
|
888
|
+
args: [{ selector: 'lib-intake-list', template: "<div class=\"container-fluid\"><h3>Ham Ya\u011F Giri\u015F Kalite Kontrol</h3><div class=\"card\"><div class=\"card-body\">\n <div class=\"btn-group mb-3\" role=\"tablist\"><button class=\"btn\" [class.btn-success]=\"query.pendingOnly\" [class.btn-outline-secondary]=\"!query.pendingOnly\" (click)=\"tab(true)\">Kalite Kontrol Bekleyenler</button><button class=\"btn\" [class.btn-success]=\"!query.pendingOnly\" [class.btn-outline-secondary]=\"query.pendingOnly\" (click)=\"tab(false)\">T\u00FCm Kay\u0131tlar</button></div>\n <div class=\"row mb-3\"><div class=\"col-md-3\"><label>Ba\u015Flang\u0131\u00E7</label><input type=\"date\" class=\"form-control\" [(ngModel)]=\"query.from\" /></div><div class=\"col-md-3\"><label>Biti\u015F</label><input type=\"date\" class=\"form-control\" [(ngModel)]=\"query.until\" /></div><div class=\"col-md-3\"><label>Ara\u00E7 Hareket T\u00FCr\u00FC</label><select class=\"form-control\" [(ngModel)]=\"query.movementTypeCode\"><option value=\"\">T\u00FCm\u00FC</option><option *ngFor=\"let type of types\" [value]=\"type.code\">{{type.name}}</option></select></div><div class=\"col-md-3 d-flex align-items-end\"><button class=\"btn btn-primary\" (click)=\"load(true)\">Filtrele</button></div></div>\n <div *ngIf=\"error\" class=\"alert alert-danger\" role=\"alert\">{{error}}</div>\n <dx-data-grid #grid class=\"intake-grid\" [dataSource]=\"dataSource\" [remoteOperations]=\"{paging: true, filtering: true, sorting: true}\" [showBorders]=\"true\" [rowAlternationEnabled]=\"true\" [columnAutoWidth]=\"true\" [allowColumnResizing]=\"true\" columnResizingMode=\"widget\" style=\"height: calc(100vh - 350px)\">\n <dxo-filter-row [visible]=\"true\"></dxo-filter-row><dxo-search-panel [visible]=\"true\" [width]=\"220\" placeholder=\"Ara\u2026\"></dxo-search-panel>\n <dxo-paging [pageSize]=\"20\"></dxo-paging><dxo-pager [visible]=\"true\" [showInfo]=\"true\" [allowedPageSizes]=\"[10,20,50]\" [showPageSizeSelector]=\"true\" [showNavigationButtons]=\"true\"></dxo-pager>\n <dxi-column caption=\"\u0130\u015Flemler\" cellTemplate=\"actions\" [allowFiltering]=\"false\" [allowSorting]=\"false\" [fixed]=\"true\" [width]=\"145\"></dxi-column>\n <dxi-column dataField=\"qualityStatus\" caption=\"Kalite Durumu\" cellTemplate=\"status\"><dxo-lookup [dataSource]=\"statuses\" valueExpr=\"value\" displayExpr=\"text\"></dxo-lookup></dxi-column>\n <dxi-column dataField=\"sequenceNumber\" caption=\"S\u0131ra No\"></dxi-column><dxi-column dataField=\"docNum\" caption=\"Belge No\" dataType=\"number\"></dxi-column><dxi-column dataField=\"gateCode\" caption=\"Kap\u0131\"></dxi-column>\n <dxi-column dataField=\"entryDate\" caption=\"Giri\u015F Tarihi / Saati\" dataType=\"datetime\" format=\"dd.MM.yyyy HH:mm\"></dxi-column><dxi-column dataField=\"movementTypeName\" caption=\"Ara\u00E7 Hareket T\u00FCr\u00FC\"></dxi-column><dxi-column dataField=\"movementDetailName\" caption=\"Detay\"></dxi-column>\n <dxi-column dataField=\"plate\" caption=\"Kamyon Plakas\u0131\"></dxi-column><dxi-column dataField=\"trailerPlate\" caption=\"Dorse Plakas\u0131\"></dxi-column><dxi-column dataField=\"driver\" caption=\"\u015Eof\u00F6r\"></dxi-column>\n <dxi-column dataField=\"partnerName\" caption=\"Muhatap\"></dxi-column><dxi-column dataField=\"shipName\" caption=\"Gemi\"></dxi-column><dxi-column dataField=\"stockTransferNumber\" caption=\"Stok Nakli\"></dxi-column>\n <dxi-column dataField=\"origin\" caption=\"Men\u015Fei\"><dxo-lookup [dataSource]=\"[{code:'Domestic',name:'\u0130\u00E7 Piyasa'},{code:'Imported',name:'\u0130thal'}]\" valueExpr=\"code\" displayExpr=\"name\"></dxo-lookup></dxi-column>\n <dxi-column dataField=\"sealNumber\" caption=\"M\u00FCh\u00FCr No\"></dxi-column><dxi-column dataField=\"analyst\" caption=\"Analizi Yapan\"></dxi-column><dxi-column dataField=\"inspectedAt\" caption=\"Kontrol Tarihi\" dataType=\"datetime\" format=\"dd.MM.yyyy HH:mm\"></dxi-column><dxi-column dataField=\"notes\" caption=\"A\u00E7\u0131klama\"></dxi-column>\n <div *dxTemplate=\"let cell of 'status'\"><span class=\"badge\" [class.badge-success]=\"cell.data.qualityStatus === 'Accepted'\" [class.badge-danger]=\"cell.data.qualityStatus === 'Rejected'\" [class.badge-warning]=\"cell.data.qualityStatus === 'Waiting' || cell.data.qualityStatus === 'Draft'\">{{statusLabel(cell.data.qualityStatus)}}</span></div>\n <div *dxTemplate=\"let cell of 'actions'\" class=\"intake-actions-cell\">\n <div ngbDropdown container=\"body\" class=\"d-inline-block\" placement=\"bottom-start top-start\">\n <button type=\"button\" ngbDropdownToggle class=\"btn btn-sm btn-primary intake-actions-toggle\"><i class=\"fa fa-cog\" aria-hidden=\"true\"></i><span>\u0130\u015Flemler</span></button>\n <div ngbDropdownMenu class=\"intake-action-menu\">\n <a ngbDropdownItem *ngIf=\"editable(cell.data) && allowed('Edit')\" [routerLink]=\"['/kalite/intake',cell.data.docEntry]\">{{cell.data.qualityStatus === 'Waiting' ? 'Kalite Kontrol Yap' : 'D\u00FCzenle'}}</a>\n <a ngbDropdownItem [routerLink]=\"['/kalite/intake',cell.data.docEntry]\" [queryParams]=\"{mode:'view'}\">\u00D6zeti G\u00F6r\u00FCnt\u00FCle</a>\n <button type=\"button\" ngbDropdownItem *ngIf=\"cell.data.qualityStatus !== 'Waiting' && allowed('Print')\" (click)=\"print(cell.data)\">Girdi Kontrol Formu Yazd\u0131r</button>\n <button type=\"button\" ngbDropdownItem *ngIf=\"editable(cell.data) && cell.data.qualityStatus !== 'Waiting' && allowed('Cancel')\" (click)=\"cancelRow = cell.data; reason = ''\">\u0130ptal Et</button>\n </div>\n </div>\n </div>\n </dx-data-grid>\n</div></div></div>\n<abp-modal [visible]=\"!!cancelRow\" (visibleChange)=\"!$event && (cancelRow = null)\" [busy]=\"busy\"><ng-template #abpHeader><h5>Kalite Kontrol\u00FCn\u00FC \u0130ptal Et</h5></ng-template><ng-template #abpBody><label>\u0130ptal Gerek\u00E7esi</label><textarea class=\"form-control\" rows=\"3\" [(ngModel)]=\"reason\"></textarea><p class=\"text-muted mt-2\">Kay\u0131t yeniden kalite kontrol bekleyenlere al\u0131n\u0131r.</p></ng-template><ng-template #abpFooter><button class=\"btn btn-secondary\" (click)=\"cancelRow = null\" [disabled]=\"busy\">Vazge\u00E7</button><button class=\"btn btn-danger\" (click)=\"cancel()\" [disabled]=\"busy || !reason.trim()\">\u0130ptal Et</button></ng-template></abp-modal>\n", styles: [".quality-loading{padding:1.5rem;text-align:center;color:#5b526c}.print-only{display:none}.quality-status{display:inline-flex;align-items:center;gap:.5rem;padding:.55rem .85rem;border:1px solid transparent;border-radius:.4rem;font-size:.9375rem;font-weight:600;line-height:1.4}.quality-status-accepted{color:#166534;background:#dcfce7;border-color:#86efac}.quality-status-rejected{color:#991b1b;background:#fee2e2;border-color:#fca5a5}.quality-status-draft{color:#1e40af;background:#dbeafe;border-color:#93c5fd}.quality-status-waiting{color:#854d0e;background:#fef3c7;border-color:#fcd34d}.vehicle-table{min-width:1950px;white-space:nowrap}.actions{min-width:130px}.quality-questions-link{display:inline-flex;align-items:center;min-height:calc(1.5em + .5rem + 2px);margin-left:.4rem;padding:.25rem .5rem;color:#9a5a00;background:#fff3d6;border:1px solid #edb85b;border-radius:.2rem;font-size:.875rem;line-height:1.5;text-decoration:none}.quality-questions-link:hover,.quality-questions-link:focus{color:#fff;background:#b86b00;border-color:#b86b00;text-decoration:none}.intake-actions-cell{display:flex;align-items:center}:host ::ng-deep .intake-grid .dx-data-row>td{vertical-align:middle}.intake-actions-toggle{display:inline-flex;align-items:center;gap:.5rem;padding:.3rem .65rem;font-family:inherit;font-size:.8125rem;line-height:1.3}.intake-action-menu{min-width:210px;margin-top:.35rem;padding:.3rem;background:#fff;border:1px solid #dee2e6;border-radius:.375rem;box-shadow:0 .25rem .75rem #0000001a}.intake-action-menu .dropdown-item{display:block;text-align:left;border:0;border-radius:.25rem;background:none;color:#343a40;padding:.5rem .65rem;font-family:inherit;font-size:.8125rem;font-weight:400;line-height:1.4;text-decoration:none;white-space:nowrap;cursor:pointer}.intake-action-menu .dropdown-item:hover,.intake-action-menu .dropdown-item:focus-visible{background:#eef2ff;color:#2446b5}.page-size{width:85px}.vehicle-info{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1rem;margin:1rem 0}.vehicle-info label{font-size:.8rem;color:#6c757d;margin-bottom:.2rem}.vehicle-info p{background:#f5f3f8;padding:.55rem;min-height:2.5rem;overflow-wrap:anywhere}.measurement-table{min-width:700px}.measurement-table th{background:#f2edf7}.measurement-table td{vertical-align:middle}.out-of-limit,.rejected-row{background:#ffe6e9!important}.out-of-limit input,.out-of-limit select{border-color:#dc3545}@media (max-width: 900px){.vehicle-info{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width: 550px){.vehicle-info{grid-template-columns:1fr}}\n"] }]
|
|
889
|
+
}], ctorParameters: function () { return [{ type: QualityApiService }, { type: i2.PermissionService }]; }, propDecorators: { grid: [{
|
|
890
|
+
type: ViewChild,
|
|
891
|
+
args: ['grid']
|
|
892
|
+
}] } });
|
|
893
|
+
|
|
894
|
+
const PRINT_STYLES = `
|
|
895
|
+
@page { size: A4 portrait; margin: 10mm; }
|
|
896
|
+
html, body { margin: 0; background: #fff !important; color: #212529; }
|
|
897
|
+
body { font-family: Arial, sans-serif; font-size: 10pt; }
|
|
898
|
+
* { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
|
899
|
+
.print-surface { width: 100%; padding: 0; }
|
|
900
|
+
.print-surface .card { box-shadow: none; border: 1px solid #ddd; margin-bottom: 4mm; }
|
|
901
|
+
.print-surface .card-body { padding: 4mm; }
|
|
902
|
+
.print-surface .vehicle-info { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 3mm; }
|
|
903
|
+
.print-surface .vehicle-info p { min-height: 0; margin-bottom: 2mm; }
|
|
904
|
+
.print-surface .row { display: flex; flex-wrap: wrap; }
|
|
905
|
+
.print-surface .col-md-3 { flex: 0 0 25%; max-width: 25%; }
|
|
906
|
+
.print-surface .col-md-4 { flex: 0 0 33.333%; max-width: 33.333%; }
|
|
907
|
+
.print-surface .col-md-12 { flex: 0 0 100%; max-width: 100%; }
|
|
908
|
+
.print-surface .table-responsive { overflow: visible; }
|
|
909
|
+
.print-surface .measurement-table { min-width: 0; width: 100%; table-layout: fixed; }
|
|
910
|
+
.print-surface .measurement-table th, .print-surface .measurement-table td { padding: 2mm; overflow-wrap: anywhere; }
|
|
911
|
+
.print-surface .measurement-table th:nth-child(1) { width: 29%; }
|
|
912
|
+
.print-surface .measurement-table th:nth-child(2) { width: 7%; }
|
|
913
|
+
.print-surface .measurement-table th:nth-child(3) { width: 25%; }
|
|
914
|
+
.print-surface .measurement-table th:nth-child(4) { width: 28%; }
|
|
915
|
+
.print-surface .measurement-table th:nth-child(5) { width: 11%; }
|
|
916
|
+
.print-surface thead { display: table-header-group; }
|
|
917
|
+
.print-surface tr, .print-surface .vehicle-info > div, .print-surface .quality-status { break-inside: avoid; }
|
|
918
|
+
.print-surface h5, .print-surface h6 { break-after: avoid; }
|
|
919
|
+
.print-value { display: block; min-height: 1.4em; white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
920
|
+
.print-surface .print-only { display: block !important; }
|
|
921
|
+
`;
|
|
922
|
+
/** Print only the form, with current control values and the application's existing colors. */
|
|
923
|
+
function printForm(source, title) {
|
|
924
|
+
var _a;
|
|
925
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
926
|
+
const owner = source.ownerDocument;
|
|
927
|
+
const content = source.cloneNode(true);
|
|
928
|
+
content.classList.add('print-surface');
|
|
929
|
+
content.querySelectorAll('button, .print-exclude, .alert, .quality-loading').forEach(x => x.remove());
|
|
930
|
+
const originals = source.querySelectorAll('input, select, textarea');
|
|
931
|
+
const copies = content.querySelectorAll('input, select, textarea');
|
|
932
|
+
// Ignore excluded editor controls before pairing, so control indexes remain identical.
|
|
933
|
+
const printableOriginals = Array.from(originals).filter(x => !x.closest('.print-exclude'));
|
|
934
|
+
copies.forEach((copy, index) => {
|
|
935
|
+
var _a;
|
|
936
|
+
const control = printableOriginals[index];
|
|
937
|
+
const value = owner.createElement('span');
|
|
938
|
+
value.className = 'print-value';
|
|
939
|
+
let text = control.getAttribute('data-print-value');
|
|
940
|
+
if (text == null) {
|
|
941
|
+
if (control.tagName === 'SELECT')
|
|
942
|
+
text = ((_a = control.selectedOptions[0]) === null || _a === void 0 ? void 0 : _a.textContent) || '';
|
|
943
|
+
else if (control instanceof HTMLInputElement && control.type === 'datetime-local' && control.value)
|
|
944
|
+
text = new Date(control.value).toLocaleString('tr-TR');
|
|
945
|
+
else if (control instanceof HTMLInputElement && control.type === 'number')
|
|
946
|
+
text = control.value.replace('.', ',');
|
|
947
|
+
else
|
|
948
|
+
text = control.value;
|
|
949
|
+
}
|
|
950
|
+
value.textContent = text || '—';
|
|
951
|
+
copy.replaceWith(value);
|
|
952
|
+
});
|
|
953
|
+
const frame = owner.createElement('iframe');
|
|
954
|
+
frame.title = 'Kalite formu yazdırma';
|
|
955
|
+
frame.setAttribute('aria-hidden', 'true');
|
|
956
|
+
frame.style.cssText = 'position:fixed;left:-10000px;top:0;width:718px;height:1047px;border:0;';
|
|
957
|
+
owner.body.appendChild(frame);
|
|
958
|
+
try {
|
|
959
|
+
const doc = frame.contentDocument;
|
|
960
|
+
const win = frame.contentWindow;
|
|
961
|
+
doc.title = title;
|
|
962
|
+
const base = doc.createElement('base');
|
|
963
|
+
base.href = owner.baseURI;
|
|
964
|
+
doc.head.appendChild(base);
|
|
965
|
+
const stylesReady = [];
|
|
966
|
+
owner.querySelectorAll('style, link[rel="stylesheet"]').forEach(style => {
|
|
967
|
+
const copy = style.cloneNode(true);
|
|
968
|
+
if (style.tagName === 'LINK') {
|
|
969
|
+
copy.href = style.href;
|
|
970
|
+
stylesReady.push(new Promise(resolve => { copy.onload = () => resolve(); copy.onerror = () => resolve(); }));
|
|
971
|
+
}
|
|
972
|
+
doc.head.appendChild(copy);
|
|
973
|
+
});
|
|
974
|
+
const style = doc.createElement('style');
|
|
975
|
+
style.textContent = PRINT_STYLES;
|
|
976
|
+
doc.head.appendChild(style);
|
|
977
|
+
doc.body.appendChild(doc.importNode(content, true));
|
|
978
|
+
yield Promise.all(stylesReady);
|
|
979
|
+
yield doc.fonts.ready;
|
|
980
|
+
yield new Promise(resolve => win.requestAnimationFrame(() => win.requestAnimationFrame(() => resolve())));
|
|
981
|
+
win.addEventListener('afterprint', () => frame.remove(), { once: true });
|
|
982
|
+
win.focus();
|
|
983
|
+
win.print();
|
|
984
|
+
// Fallback for browsers that omit afterprint, without removing the frame during preview.
|
|
985
|
+
(_a = owner.defaultView) === null || _a === void 0 ? void 0 : _a.setTimeout(() => frame.remove(), 300000);
|
|
986
|
+
}
|
|
987
|
+
catch (error) {
|
|
988
|
+
frame.remove();
|
|
989
|
+
throw error;
|
|
990
|
+
}
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
class IntakeFormComponent {
|
|
995
|
+
constructor(api, route, router, permissions) {
|
|
996
|
+
this.api = api;
|
|
997
|
+
this.route = route;
|
|
998
|
+
this.router = router;
|
|
999
|
+
this.permissions = permissions;
|
|
1000
|
+
this.form = null;
|
|
1001
|
+
this.tanks = [];
|
|
1002
|
+
this.busy = false;
|
|
1003
|
+
this.error = '';
|
|
1004
|
+
this.success = '';
|
|
1005
|
+
this.validationError = '';
|
|
1006
|
+
this.decision = '';
|
|
1007
|
+
this.viewOnly = false;
|
|
1008
|
+
this.compositeEditor = false;
|
|
1009
|
+
this.compositeMeasurements = [];
|
|
1010
|
+
this.statusLabel = statusLabel;
|
|
1011
|
+
this.destroy = new Subject();
|
|
1012
|
+
}
|
|
1013
|
+
ngOnInit() {
|
|
1014
|
+
this.route.paramMap.pipe(takeUntil(this.destroy)).subscribe(params => { this.viewOnly = this.route.snapshot.queryParamMap.get('mode') === 'view'; this.load(Number(params.get('id'))); });
|
|
1015
|
+
this.api.tanks().subscribe({ next: tanks => this.tanks = tanks.filter(x => x.active), error: e => this.error = errorMessage(e) });
|
|
1016
|
+
}
|
|
1017
|
+
ngOnDestroy() { this.destroy.next(); this.destroy.complete(); }
|
|
1018
|
+
allowed(action) { return this.permissions.getGrantedPolicy('Kalite.Intake.' + action); }
|
|
1019
|
+
get editable() { var _a; return !!((_a = this.form) === null || _a === void 0 ? void 0 : _a.canEdit) && !this.viewOnly && this.allowed('Edit'); }
|
|
1020
|
+
get parameters() { var _a, _b; return ((_b = (_a = this.form) === null || _a === void 0 ? void 0 : _a.inspection.templateSnapshot) === null || _b === void 0 ? void 0 : _b.parameters.filter(x => x.active).sort((a, b) => a.order - b.order)) || []; }
|
|
1021
|
+
get palm() { var _a, _b; return ((_b = (_a = this.form) === null || _a === void 0 ? void 0 : _a.details.find(x => { var _a; return x.code === ((_a = this.form) === null || _a === void 0 ? void 0 : _a.inspection.movementDetailCode); })) === null || _b === void 0 ? void 0 : _b.profile) === 'PALM'; }
|
|
1022
|
+
localTime(value) { const d = new Date(value); return localDate(d) + 'T' + String(d.getHours()).padStart(2, '0') + ':' + String(d.getMinutes()).padStart(2, '0'); }
|
|
1023
|
+
load(id) {
|
|
1024
|
+
if (!Number.isInteger(id) || id <= 0) {
|
|
1025
|
+
this.error = 'Geçerli bir araç kaydı seçin.';
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
1028
|
+
this.busy = true;
|
|
1029
|
+
this.error = '';
|
|
1030
|
+
this.api.intake(id).subscribe({ next: form => { this.form = form; form.inspection.inspectedAt = this.localTime(form.inspection.inspectedAt); this.decision = ''; this.busy = false; }, error: e => { this.error = errorMessage(e); this.busy = false; } });
|
|
1031
|
+
}
|
|
1032
|
+
detailChanged() {
|
|
1033
|
+
if (!this.form)
|
|
1034
|
+
return;
|
|
1035
|
+
this.busy = true;
|
|
1036
|
+
this.api.intakeTemplate(this.form.inspection.movementDetailCode).subscribe({ next: t => {
|
|
1037
|
+
if (this.form) {
|
|
1038
|
+
this.form.inspection.templateSnapshot = t;
|
|
1039
|
+
this.form.inspection.measurements = [];
|
|
1040
|
+
this.form.compositeSample = null;
|
|
1041
|
+
this.compositeEditor = false;
|
|
1042
|
+
}
|
|
1043
|
+
this.busy = false;
|
|
1044
|
+
this.changed();
|
|
1045
|
+
}, error: e => { this.error = errorMessage(e); this.busy = false; } });
|
|
1046
|
+
}
|
|
1047
|
+
measurement(p, composite = false) {
|
|
1048
|
+
const values = composite ? this.compositeMeasurements : this.form.inspection.measurements;
|
|
1049
|
+
let value = values.find(x => x.parameterCode === p.code);
|
|
1050
|
+
if (!value) {
|
|
1051
|
+
value = { parameterCode: p.code, number: null, text: '' };
|
|
1052
|
+
values.push(value);
|
|
1053
|
+
}
|
|
1054
|
+
return value;
|
|
1055
|
+
}
|
|
1056
|
+
limitLabel(p) {
|
|
1057
|
+
var _a, _b;
|
|
1058
|
+
const i = (_a = this.form) === null || _a === void 0 ? void 0 : _a.inspection;
|
|
1059
|
+
if (!i)
|
|
1060
|
+
return '—';
|
|
1061
|
+
const l = applicableLimit(((_b = i.templateSnapshot) === null || _b === void 0 ? void 0 : _b.limits) || [], p.code, i.inspectedAt.slice(0, 10), i.oilType, i.origin);
|
|
1062
|
+
if (!l)
|
|
1063
|
+
return '—';
|
|
1064
|
+
const range = l.expectedText || (l.minimum != null && l.maximum != null ? `${l.minimum} – ${l.maximum}` : l.minimum != null ? `≥ ${l.minimum}` : l.maximum != null ? `≤ ${l.maximum}` : '—');
|
|
1065
|
+
return range + (l.nominal != null ? ` · Nominal: ${l.nominal}` : '');
|
|
1066
|
+
}
|
|
1067
|
+
inputStep(p) { return Math.pow(10, -p.decimalPlaces); }
|
|
1068
|
+
changed(composite = false) {
|
|
1069
|
+
var _a;
|
|
1070
|
+
const i = (_a = this.form) === null || _a === void 0 ? void 0 : _a.inspection;
|
|
1071
|
+
if (!(i === null || i === void 0 ? void 0 : i.templateSnapshot))
|
|
1072
|
+
return;
|
|
1073
|
+
try {
|
|
1074
|
+
recalculate(this.parameters, composite ? this.compositeMeasurements : i.measurements, i.templateSnapshot.limits, i.inspectedAt.slice(0, 10), i.oilType, i.origin);
|
|
1075
|
+
this.error = '';
|
|
1076
|
+
}
|
|
1077
|
+
catch (e) {
|
|
1078
|
+
this.error = e instanceof Error ? e.message : 'Hesaplama yapılamadı.';
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
payload() {
|
|
1082
|
+
const i = this.form.inspection;
|
|
1083
|
+
return { vehicleEntryId: i.vehicleEntryId, movementDetailCode: i.movementDetailCode, origin: i.origin || '', tankCode: i.tankCode || '', oilType: i.oilType || '',
|
|
1084
|
+
batchNumber: i.batchNumber || '', notes: i.notes || '', analyst: i.analyst, inspectedAt: new Date(i.inspectedAt).toISOString(), revision: i.revision,
|
|
1085
|
+
measurements: i.measurements, decision: this.decision || undefined };
|
|
1086
|
+
}
|
|
1087
|
+
save(approve) {
|
|
1088
|
+
var _a;
|
|
1089
|
+
if (!this.form || !this.editable)
|
|
1090
|
+
return;
|
|
1091
|
+
if (!this.form.inspection.inspectedAt || Number.isNaN(Date.parse(this.form.inspection.inspectedAt))) {
|
|
1092
|
+
this.validationError = 'Kontrol tarihi ve saatini girin.';
|
|
1093
|
+
this.error = this.validationError;
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1096
|
+
if (approve && !this.decision) {
|
|
1097
|
+
this.validationError = 'Kabul veya Ret seçin.';
|
|
1098
|
+
this.error = this.validationError;
|
|
1099
|
+
return;
|
|
1100
|
+
}
|
|
1101
|
+
if (approve && this.decision === 'Rejected' && !((_a = this.form.inspection.notes) === null || _a === void 0 ? void 0 : _a.trim())) {
|
|
1102
|
+
this.validationError = 'Ret gerekçesi girin.';
|
|
1103
|
+
this.error = this.validationError;
|
|
1104
|
+
return;
|
|
1105
|
+
}
|
|
1106
|
+
if (!approve)
|
|
1107
|
+
this.decision = '';
|
|
1108
|
+
this.busy = true;
|
|
1109
|
+
this.error = '';
|
|
1110
|
+
this.validationError = '';
|
|
1111
|
+
this.api.saveIntake(this.payload()).subscribe({ next: i => { this.success = approve ? 'Kalite kararı kaydedildi.' : 'Taslak kaydedildi.'; this.form.inspection = i; i.inspectedAt = this.localTime(i.inspectedAt); this.busy = false; }, error: e => { this.error = errorMessage(e); this.busy = false; } });
|
|
1112
|
+
}
|
|
1113
|
+
beginComposite() { this.compositeEditor = true; this.compositeMeasurements = []; }
|
|
1114
|
+
saveComposite() {
|
|
1115
|
+
if (!this.form)
|
|
1116
|
+
return;
|
|
1117
|
+
if (!this.form.inspection.inspectedAt || Number.isNaN(Date.parse(this.form.inspection.inspectedAt))) {
|
|
1118
|
+
this.error = 'Numune tarihi ve saatini girin.';
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
1121
|
+
this.busy = true;
|
|
1122
|
+
this.api.saveComposite(Object.assign(Object.assign({}, this.payload()), { revision: 0, measurements: this.compositeMeasurements })).subscribe({ next: sample => { this.form.compositeSample = sample; this.compositeEditor = false; this.busy = false; }, error: e => { this.error = errorMessage(e); this.busy = false; } });
|
|
1123
|
+
}
|
|
1124
|
+
refreshComposite() {
|
|
1125
|
+
if (!this.form)
|
|
1126
|
+
return;
|
|
1127
|
+
const i = this.form.inspection;
|
|
1128
|
+
this.api.intake(i.vehicleEntryId, i.movementDetailCode, i.batchNumber).subscribe({ next: result => this.form.compositeSample = result.compositeSample, error: e => this.error = errorMessage(e) });
|
|
1129
|
+
}
|
|
1130
|
+
print() {
|
|
1131
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1132
|
+
if (!this.form || !this.printArea || this.busy || !this.allowed('Print'))
|
|
1133
|
+
return;
|
|
1134
|
+
try {
|
|
1135
|
+
yield printForm(this.printArea.nativeElement, `Girdi-Kontrol-${this.form.vehicle.docEntry}`);
|
|
1136
|
+
}
|
|
1137
|
+
catch (e) {
|
|
1138
|
+
this.error = errorMessage(e);
|
|
1139
|
+
}
|
|
1140
|
+
});
|
|
1141
|
+
}
|
|
1142
|
+
back() { this.router.navigate(['/kalite/intake']); }
|
|
1143
|
+
}
|
|
1144
|
+
IntakeFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: IntakeFormComponent, deps: [{ token: QualityApiService }, { token: i2$1.ActivatedRoute }, { token: i2$1.Router }, { token: i2.PermissionService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1145
|
+
IntakeFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: IntakeFormComponent, selector: "lib-intake-form", viewQueries: [{ propertyName: "printArea", first: true, predicate: ["printArea"], descendants: true }], ngImport: i0, template: "<div class=\"container-fluid\" #printArea>\n <div class=\"d-flex justify-content-between align-items-center mb-3\"><h3>Ham Ya\u011F Giri\u015F Kalite Kontrol</h3><button class=\"btn btn-outline-secondary\" (click)=\"back()\">Listeye D\u00F6n</button></div>\n <div *ngIf=\"error\" class=\"alert alert-danger\" role=\"alert\">{{ error }}</div><div *ngIf=\"success\" class=\"alert alert-success\">{{ success }}</div>\n <div *ngIf=\"busy\" class=\"quality-loading\" role=\"status\"><span class=\"spinner-border spinner-border-sm mr-2\"></span> \u0130\u015Flem s\u00FCr\u00FCyor\u2026</div>\n <ng-container *ngIf=\"form as f\">\n <div class=\"card mb-3\"><div class=\"card-body\"><h5>Ara\u00E7 / Sevkiyat Bilgileri</h5>\n <div class=\"vehicle-info\">\n <div><label>S\u0131ra / Belge No</label><p>{{ f.vehicle.sequenceNumber }} / {{ f.vehicle.docNum }}</p></div><div><label>Giri\u015F Tarihi / Saati</label><p>{{ f.vehicle.entryDate | date:'dd.MM.yyyy HH:mm' }}</p></div>\n <div><label>Kap\u0131 / Hareket T\u00FCr\u00FC</label><p>{{ f.vehicle.gateCode }} / {{ f.vehicle.movementTypeName }}</p></div><div><label>Kamyon / Dorse</label><p>{{ f.vehicle.plate }} / {{ f.vehicle.trailerPlate || '\u2014' }}</p></div>\n <div><label>\u015Eof\u00F6r / Telefon</label><p>{{ f.vehicle.driver }} / {{ f.vehicle.driverPhone || '\u2014' }}</p></div><div><label>T.C. Kimlik / M\u00FCh\u00FCr</label><p>{{ f.vehicle.identityNumber || '\u2014' }} / {{ f.vehicle.sealNumber || '\u2014' }}</p></div>\n <div><label>Muhatap / Gemi</label><p>{{ f.vehicle.partnerName || '\u2014' }} / {{ f.vehicle.shipName || '\u2014' }}</p></div><div><label>Stok Nakli / Mal Giri\u015Fi / Sipari\u015F</label><p>{{ f.vehicle.stockTransferNumber || '\u2014' }} / {{ f.vehicle.receiptNumber || '\u2014' }} / {{ f.vehicle.orderNumber || '\u2014' }}</p></div>\n </div>\n <div class=\"row\">\n <div class=\"col-md-4\"><label>Ara\u00E7 Hareket T\u00FCr\u00FC Detay\u0131</label><select class=\"form-control\" [(ngModel)]=\"f.inspection.movementDetailCode\" (change)=\"detailChanged()\" [disabled]=\"!editable || busy || (f.details.length === 1 && !f.details[0].detailCode)\"><option value=\"\">Se\u00E7in</option><option *ngFor=\"let d of f.details\" [value]=\"d.code\">{{ d.name || f.vehicle.movementTypeName }}{{ !d.detailCode ? ' (detays\u0131z)' : '' }}</option></select></div>\n <div class=\"col-md-4\"><label>Men\u015Fei</label><select class=\"form-control\" [(ngModel)]=\"f.inspection.origin\" (change)=\"changed()\" [disabled]=\"!editable || busy\"><option value=\"\">Se\u00E7in</option><option value=\"Domestic\">\u0130\u00E7 Piyasa</option><option value=\"Imported\">\u0130thal</option></select></div>\n <div class=\"col-md-4\"><label>Kalite Durumu</label><p class=\"mt-2\">\n <span class=\"quality-status\" role=\"status\"\n [class.quality-status-accepted]=\"f.inspection.revision && f.inspection.status === 'Accepted'\"\n [class.quality-status-rejected]=\"f.inspection.revision && f.inspection.status === 'Rejected'\"\n [class.quality-status-draft]=\"f.inspection.revision && f.inspection.status === 'Draft'\"\n [class.quality-status-waiting]=\"!f.inspection.revision || f.inspection.status === 'Waiting'\">\n <i class=\"fa\" aria-hidden=\"true\"\n [class.fa-check-circle]=\"f.inspection.revision && f.inspection.status === 'Accepted'\"\n [class.fa-times-circle]=\"f.inspection.revision && f.inspection.status === 'Rejected'\"\n [class.fa-edit]=\"f.inspection.revision && f.inspection.status === 'Draft'\"\n [class.fa-clock]=\"!f.inspection.revision || f.inspection.status === 'Waiting'\"></i>\n {{ statusLabel(f.inspection.revision ? f.inspection.status : 'Waiting') }}\n </span>\n </p></div>\n </div>\n </div></div>\n <div class=\"card mb-3\"><div class=\"card-body\">\n <h5>{{ f.inspection.templateSnapshot?.form?.name || '\u00D6l\u00E7\u00FCm / Parametreler' }} <small>{{ f.inspection.templateSnapshot?.form?.documentCode }}</small></h5>\n <p class=\"print-only text-muted\">Yay\u0131n: {{ f.inspection.templateSnapshot?.form?.publicationDate | date:'dd.MM.yyyy' }} \u00B7 Revizyon: {{ f.inspection.templateSnapshot?.form?.revisionDate | date:'dd.MM.yyyy' }} / {{ f.inspection.templateSnapshot?.form?.revisionNumber }}</p>\n <p *ngIf=\"!parameters.length\" class=\"text-muted\">Detay se\u00E7in. Bu kaleme ait form ve sorular Kalite Parametreleri ekran\u0131ndan tan\u0131mlanmal\u0131d\u0131r.</p>\n <div class=\"table-responsive\"><table class=\"table table-bordered table-sm measurement-table\" *ngIf=\"parameters.length\">\n <thead><tr><th>Soru / Parametre</th><th>Birim</th><th>Nominal / Limit</th><th>\u00D6l\u00E7\u00FCm De\u011Feri / Yan\u0131t</th><th>Uygunluk</th></tr></thead>\n <tbody><tr *ngFor=\"let p of parameters\" [class.out-of-limit]=\"measurement(p).outOfLimit\">\n <td>{{ p.name }}<span *ngIf=\"p.required\" class=\"text-danger\"> *</span></td><td>{{ p.unit || '\u2014' }}</td><td>{{ limitLabel(p) }}</td>\n <td><input *ngIf=\"p.valueType === 'Number'\" type=\"number\" class=\"form-control form-control-sm\" [(ngModel)]=\"measurement(p).number\" (ngModelChange)=\"changed()\" [attr.step]=\"inputStep(p)\" [disabled]=\"!editable || p.calculated || busy\" [attr.aria-label]=\"p.name\" />\n <select *ngIf=\"p.valueType === 'Choice'\" class=\"form-control form-control-sm\" [(ngModel)]=\"measurement(p).text\" (change)=\"changed()\" [disabled]=\"!editable || busy\"><option value=\"\">Se\u00E7in</option><option *ngFor=\"let option of p.options\" [value]=\"option\">{{ option }}</option></select>\n <input *ngIf=\"p.valueType === 'Text'\" class=\"form-control form-control-sm\" [(ngModel)]=\"measurement(p).text\" (ngModelChange)=\"changed()\" [disabled]=\"!editable || busy\" [attr.aria-label]=\"p.name\" />\n </td><td><span *ngIf=\"measurement(p).outOfLimit\" class=\"badge badge-danger\">Limit D\u0131\u015F\u0131</span><span *ngIf=\"!measurement(p).outOfLimit && (measurement(p).number != null || measurement(p).text)\" class=\"badge badge-success\">{{ p.calculated ? 'Otomatik' : 'Uygun' }}</span></td>\n </tr></tbody>\n </table></div>\n <div *ngIf=\"palm\" class=\"border rounded p-3 mt-3\">\n <h6>Gemi / Parti Kompozit Numunesi</h6><label>Parti Kodu</label><div class=\"d-flex\"><input class=\"form-control\" [(ngModel)]=\"f.inspection.batchNumber\" [disabled]=\"!editable || busy\" /><button class=\"btn btn-outline-secondary ml-2\" (click)=\"refreshComposite()\">Numuneyi Getir</button></div>\n <p class=\"text-muted mt-2\">Kaynak mal giri\u015Fi veya parti koduyla ili\u015Fkilendirilen numune di\u011Fer ara\u00E7larda salt okunur g\u00F6sterilir.</p>\n <ng-container *ngIf=\"f.compositeSample as sample\"><p>{{ sample.analyst }} \u00B7 {{ sample.sampledAt | date:'dd.MM.yyyy HH:mm' }}</p><div class=\"row\"><div class=\"col-md-3 mb-2\" *ngFor=\"let value of sample.measurements\"><strong>{{ value.parameterName }}</strong>: {{ value.number != null ? value.number : value.text }} {{ value.unit }}</div></div></ng-container>\n <button *ngIf=\"!f.compositeSample && editable && allowed('Composite') && !compositeEditor\" class=\"btn btn-outline-primary\" (click)=\"beginComposite()\">Kompozit Numune Gir</button>\n <div *ngIf=\"compositeEditor\" class=\"print-exclude\"><div class=\"row\"><div class=\"col-md-3 mb-2\" *ngFor=\"let p of parameters\"><label>{{ p.name }}</label><input *ngIf=\"p.valueType === 'Number'\" type=\"number\" class=\"form-control\" [(ngModel)]=\"measurement(p, true).number\" (ngModelChange)=\"changed(true)\" [disabled]=\"p.calculated || busy\" /><select *ngIf=\"p.valueType === 'Choice'\" class=\"form-control\" [(ngModel)]=\"measurement(p, true).text\" (change)=\"changed(true)\"><option value=\"\"></option><option *ngFor=\"let option of p.options\" [value]=\"option\">{{ option }}</option></select><input *ngIf=\"p.valueType === 'Text'\" class=\"form-control\" [(ngModel)]=\"measurement(p, true).text\" /></div></div><button class=\"btn btn-primary\" (click)=\"saveComposite()\" [disabled]=\"busy\">Numuneyi Kaydet</button><button class=\"btn btn-secondary ml-2\" (click)=\"compositeEditor = false\">Vazge\u00E7</button></div>\n </div>\n </div></div>\n <div class=\"card\"><div class=\"card-body\"><h5>De\u011Ferlendirme</h5><div class=\"row\">\n <div class=\"col-md-3\"><label>Genel De\u011Ferlendirme</label><select class=\"form-control\" [(ngModel)]=\"decision\" [attr.data-print-value]=\"statusLabel(decision || (f.inspection.revision ? f.inspection.status : 'Waiting'))\" [disabled]=\"!editable || busy\"><option value=\"\">Se\u00E7in</option><option *ngIf=\"allowed('Accept')\" value=\"Accepted\">Kabul</option><option *ngIf=\"allowed('Reject')\" value=\"Rejected\">Ret</option></select></div>\n <div class=\"col-md-3\"><label>Analizi Yapan *</label><input class=\"form-control\" [(ngModel)]=\"f.inspection.analyst\" [disabled]=\"!editable || busy\" /></div>\n <div class=\"col-md-3\"><label>Kontrol Tarihi / Saati *</label><input type=\"datetime-local\" class=\"form-control\" [(ngModel)]=\"f.inspection.inspectedAt\" (change)=\"changed()\" [disabled]=\"!editable || busy\" /></div>\n <div class=\"col-md-3\"><label>Miktar (kg)</label><input class=\"form-control\" [value]=\"f.inspection.quantityKg == null ? 'Tart\u0131m sonras\u0131 gelir' : f.inspection.quantityKg\" disabled /></div>\n <div class=\"col-md-4 mt-3\"><label>Tank No</label><select class=\"form-control\" [(ngModel)]=\"f.inspection.tankCode\" [disabled]=\"!editable || busy\"><option value=\"\">Se\u00E7in</option><option *ngFor=\"let tank of tanks\" [value]=\"tank.code\">{{ tank.name }}</option></select></div>\n <div class=\"col-md-4 mt-3\"><label>Ya\u011F Cinsi</label><select class=\"form-control\" [(ngModel)]=\"f.inspection.oilType\" (change)=\"changed()\" [disabled]=\"!editable || busy\"><option value=\"\">Se\u00E7in</option><option>Ay\u00E7i\u00E7ek</option><option>Rafine Ay\u00E7i\u00E7ek</option><option>Palm Oil</option><option>Palm Olein</option></select></div>\n <div class=\"col-md-12 mt-3\"><label>A\u00E7\u0131klama / Di\u011Fer <span *ngIf=\"decision === 'Rejected'\">*</span></label><textarea rows=\"3\" class=\"form-control\" [(ngModel)]=\"f.inspection.notes\" [disabled]=\"!editable || busy\"></textarea></div>\n </div><div *ngIf=\"validationError\" class=\"alert alert-danger mt-3 mb-2\" role=\"alert\">{{ validationError }}</div><div class=\"mt-3\"><button *ngIf=\"editable\" class=\"btn btn-outline-primary mr-2\" (click)=\"save(false)\" [disabled]=\"busy || !parameters.length\">Kaydet</button><button *ngIf=\"editable && (allowed('Accept') || allowed('Reject'))\" class=\"btn btn-primary mr-2\" (click)=\"save(true)\" [disabled]=\"busy || !parameters.length\">Kaydet ve Onayla</button><button *ngIf=\"allowed('Print')\" class=\"btn btn-outline-secondary mr-2\" (click)=\"print()\" [disabled]=\"busy || !f.inspection.revision\">Formu Yazd\u0131r</button><button class=\"btn btn-secondary\" (click)=\"back()\">Vazge\u00E7</button></div>\n <p *ngIf=\"!f.canEdit\" class=\"text-muted mt-3\">Ara\u00E7 tart\u0131ma girdi\u011Fi, \u00E7\u0131kt\u0131\u011F\u0131 veya iptal edildi\u011Fi i\u00E7in kay\u0131t salt okunur.</p>\n </div></div>\n </ng-container>\n</div>\n", styles: [".quality-loading{padding:1.5rem;text-align:center;color:#5b526c}.print-only{display:none}.quality-status{display:inline-flex;align-items:center;gap:.5rem;padding:.55rem .85rem;border:1px solid transparent;border-radius:.4rem;font-size:.9375rem;font-weight:600;line-height:1.4}.quality-status-accepted{color:#166534;background:#dcfce7;border-color:#86efac}.quality-status-rejected{color:#991b1b;background:#fee2e2;border-color:#fca5a5}.quality-status-draft{color:#1e40af;background:#dbeafe;border-color:#93c5fd}.quality-status-waiting{color:#854d0e;background:#fef3c7;border-color:#fcd34d}.vehicle-table{min-width:1950px;white-space:nowrap}.actions{min-width:130px}.quality-questions-link{display:inline-flex;align-items:center;min-height:calc(1.5em + .5rem + 2px);margin-left:.4rem;padding:.25rem .5rem;color:#9a5a00;background:#fff3d6;border:1px solid #edb85b;border-radius:.2rem;font-size:.875rem;line-height:1.5;text-decoration:none}.quality-questions-link:hover,.quality-questions-link:focus{color:#fff;background:#b86b00;border-color:#b86b00;text-decoration:none}.intake-actions-cell{display:flex;align-items:center}:host ::ng-deep .intake-grid .dx-data-row>td{vertical-align:middle}.intake-actions-toggle{display:inline-flex;align-items:center;gap:.5rem;padding:.3rem .65rem;font-family:inherit;font-size:.8125rem;line-height:1.3}.intake-action-menu{min-width:210px;margin-top:.35rem;padding:.3rem;background:#fff;border:1px solid #dee2e6;border-radius:.375rem;box-shadow:0 .25rem .75rem #0000001a}.intake-action-menu .dropdown-item{display:block;text-align:left;border:0;border-radius:.25rem;background:none;color:#343a40;padding:.5rem .65rem;font-family:inherit;font-size:.8125rem;font-weight:400;line-height:1.4;text-decoration:none;white-space:nowrap;cursor:pointer}.intake-action-menu .dropdown-item:hover,.intake-action-menu .dropdown-item:focus-visible{background:#eef2ff;color:#2446b5}.page-size{width:85px}.vehicle-info{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1rem;margin:1rem 0}.vehicle-info label{font-size:.8rem;color:#6c757d;margin-bottom:.2rem}.vehicle-info p{background:#f5f3f8;padding:.55rem;min-height:2.5rem;overflow-wrap:anywhere}.measurement-table{min-width:700px}.measurement-table th{background:#f2edf7}.measurement-table td{vertical-align:middle}.out-of-limit,.rejected-row{background:#ffe6e9!important}.out-of-limit input,.out-of-limit select{border-color:#dc3545}@media (max-width: 900px){.vehicle-info{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width: 550px){.vehicle-info{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.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: i5.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i3.DatePipe, name: "date" }] });
|
|
1146
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: IntakeFormComponent, decorators: [{
|
|
1147
|
+
type: Component,
|
|
1148
|
+
args: [{ selector: 'lib-intake-form', template: "<div class=\"container-fluid\" #printArea>\n <div class=\"d-flex justify-content-between align-items-center mb-3\"><h3>Ham Ya\u011F Giri\u015F Kalite Kontrol</h3><button class=\"btn btn-outline-secondary\" (click)=\"back()\">Listeye D\u00F6n</button></div>\n <div *ngIf=\"error\" class=\"alert alert-danger\" role=\"alert\">{{ error }}</div><div *ngIf=\"success\" class=\"alert alert-success\">{{ success }}</div>\n <div *ngIf=\"busy\" class=\"quality-loading\" role=\"status\"><span class=\"spinner-border spinner-border-sm mr-2\"></span> \u0130\u015Flem s\u00FCr\u00FCyor\u2026</div>\n <ng-container *ngIf=\"form as f\">\n <div class=\"card mb-3\"><div class=\"card-body\"><h5>Ara\u00E7 / Sevkiyat Bilgileri</h5>\n <div class=\"vehicle-info\">\n <div><label>S\u0131ra / Belge No</label><p>{{ f.vehicle.sequenceNumber }} / {{ f.vehicle.docNum }}</p></div><div><label>Giri\u015F Tarihi / Saati</label><p>{{ f.vehicle.entryDate | date:'dd.MM.yyyy HH:mm' }}</p></div>\n <div><label>Kap\u0131 / Hareket T\u00FCr\u00FC</label><p>{{ f.vehicle.gateCode }} / {{ f.vehicle.movementTypeName }}</p></div><div><label>Kamyon / Dorse</label><p>{{ f.vehicle.plate }} / {{ f.vehicle.trailerPlate || '\u2014' }}</p></div>\n <div><label>\u015Eof\u00F6r / Telefon</label><p>{{ f.vehicle.driver }} / {{ f.vehicle.driverPhone || '\u2014' }}</p></div><div><label>T.C. Kimlik / M\u00FCh\u00FCr</label><p>{{ f.vehicle.identityNumber || '\u2014' }} / {{ f.vehicle.sealNumber || '\u2014' }}</p></div>\n <div><label>Muhatap / Gemi</label><p>{{ f.vehicle.partnerName || '\u2014' }} / {{ f.vehicle.shipName || '\u2014' }}</p></div><div><label>Stok Nakli / Mal Giri\u015Fi / Sipari\u015F</label><p>{{ f.vehicle.stockTransferNumber || '\u2014' }} / {{ f.vehicle.receiptNumber || '\u2014' }} / {{ f.vehicle.orderNumber || '\u2014' }}</p></div>\n </div>\n <div class=\"row\">\n <div class=\"col-md-4\"><label>Ara\u00E7 Hareket T\u00FCr\u00FC Detay\u0131</label><select class=\"form-control\" [(ngModel)]=\"f.inspection.movementDetailCode\" (change)=\"detailChanged()\" [disabled]=\"!editable || busy || (f.details.length === 1 && !f.details[0].detailCode)\"><option value=\"\">Se\u00E7in</option><option *ngFor=\"let d of f.details\" [value]=\"d.code\">{{ d.name || f.vehicle.movementTypeName }}{{ !d.detailCode ? ' (detays\u0131z)' : '' }}</option></select></div>\n <div class=\"col-md-4\"><label>Men\u015Fei</label><select class=\"form-control\" [(ngModel)]=\"f.inspection.origin\" (change)=\"changed()\" [disabled]=\"!editable || busy\"><option value=\"\">Se\u00E7in</option><option value=\"Domestic\">\u0130\u00E7 Piyasa</option><option value=\"Imported\">\u0130thal</option></select></div>\n <div class=\"col-md-4\"><label>Kalite Durumu</label><p class=\"mt-2\">\n <span class=\"quality-status\" role=\"status\"\n [class.quality-status-accepted]=\"f.inspection.revision && f.inspection.status === 'Accepted'\"\n [class.quality-status-rejected]=\"f.inspection.revision && f.inspection.status === 'Rejected'\"\n [class.quality-status-draft]=\"f.inspection.revision && f.inspection.status === 'Draft'\"\n [class.quality-status-waiting]=\"!f.inspection.revision || f.inspection.status === 'Waiting'\">\n <i class=\"fa\" aria-hidden=\"true\"\n [class.fa-check-circle]=\"f.inspection.revision && f.inspection.status === 'Accepted'\"\n [class.fa-times-circle]=\"f.inspection.revision && f.inspection.status === 'Rejected'\"\n [class.fa-edit]=\"f.inspection.revision && f.inspection.status === 'Draft'\"\n [class.fa-clock]=\"!f.inspection.revision || f.inspection.status === 'Waiting'\"></i>\n {{ statusLabel(f.inspection.revision ? f.inspection.status : 'Waiting') }}\n </span>\n </p></div>\n </div>\n </div></div>\n <div class=\"card mb-3\"><div class=\"card-body\">\n <h5>{{ f.inspection.templateSnapshot?.form?.name || '\u00D6l\u00E7\u00FCm / Parametreler' }} <small>{{ f.inspection.templateSnapshot?.form?.documentCode }}</small></h5>\n <p class=\"print-only text-muted\">Yay\u0131n: {{ f.inspection.templateSnapshot?.form?.publicationDate | date:'dd.MM.yyyy' }} \u00B7 Revizyon: {{ f.inspection.templateSnapshot?.form?.revisionDate | date:'dd.MM.yyyy' }} / {{ f.inspection.templateSnapshot?.form?.revisionNumber }}</p>\n <p *ngIf=\"!parameters.length\" class=\"text-muted\">Detay se\u00E7in. Bu kaleme ait form ve sorular Kalite Parametreleri ekran\u0131ndan tan\u0131mlanmal\u0131d\u0131r.</p>\n <div class=\"table-responsive\"><table class=\"table table-bordered table-sm measurement-table\" *ngIf=\"parameters.length\">\n <thead><tr><th>Soru / Parametre</th><th>Birim</th><th>Nominal / Limit</th><th>\u00D6l\u00E7\u00FCm De\u011Feri / Yan\u0131t</th><th>Uygunluk</th></tr></thead>\n <tbody><tr *ngFor=\"let p of parameters\" [class.out-of-limit]=\"measurement(p).outOfLimit\">\n <td>{{ p.name }}<span *ngIf=\"p.required\" class=\"text-danger\"> *</span></td><td>{{ p.unit || '\u2014' }}</td><td>{{ limitLabel(p) }}</td>\n <td><input *ngIf=\"p.valueType === 'Number'\" type=\"number\" class=\"form-control form-control-sm\" [(ngModel)]=\"measurement(p).number\" (ngModelChange)=\"changed()\" [attr.step]=\"inputStep(p)\" [disabled]=\"!editable || p.calculated || busy\" [attr.aria-label]=\"p.name\" />\n <select *ngIf=\"p.valueType === 'Choice'\" class=\"form-control form-control-sm\" [(ngModel)]=\"measurement(p).text\" (change)=\"changed()\" [disabled]=\"!editable || busy\"><option value=\"\">Se\u00E7in</option><option *ngFor=\"let option of p.options\" [value]=\"option\">{{ option }}</option></select>\n <input *ngIf=\"p.valueType === 'Text'\" class=\"form-control form-control-sm\" [(ngModel)]=\"measurement(p).text\" (ngModelChange)=\"changed()\" [disabled]=\"!editable || busy\" [attr.aria-label]=\"p.name\" />\n </td><td><span *ngIf=\"measurement(p).outOfLimit\" class=\"badge badge-danger\">Limit D\u0131\u015F\u0131</span><span *ngIf=\"!measurement(p).outOfLimit && (measurement(p).number != null || measurement(p).text)\" class=\"badge badge-success\">{{ p.calculated ? 'Otomatik' : 'Uygun' }}</span></td>\n </tr></tbody>\n </table></div>\n <div *ngIf=\"palm\" class=\"border rounded p-3 mt-3\">\n <h6>Gemi / Parti Kompozit Numunesi</h6><label>Parti Kodu</label><div class=\"d-flex\"><input class=\"form-control\" [(ngModel)]=\"f.inspection.batchNumber\" [disabled]=\"!editable || busy\" /><button class=\"btn btn-outline-secondary ml-2\" (click)=\"refreshComposite()\">Numuneyi Getir</button></div>\n <p class=\"text-muted mt-2\">Kaynak mal giri\u015Fi veya parti koduyla ili\u015Fkilendirilen numune di\u011Fer ara\u00E7larda salt okunur g\u00F6sterilir.</p>\n <ng-container *ngIf=\"f.compositeSample as sample\"><p>{{ sample.analyst }} \u00B7 {{ sample.sampledAt | date:'dd.MM.yyyy HH:mm' }}</p><div class=\"row\"><div class=\"col-md-3 mb-2\" *ngFor=\"let value of sample.measurements\"><strong>{{ value.parameterName }}</strong>: {{ value.number != null ? value.number : value.text }} {{ value.unit }}</div></div></ng-container>\n <button *ngIf=\"!f.compositeSample && editable && allowed('Composite') && !compositeEditor\" class=\"btn btn-outline-primary\" (click)=\"beginComposite()\">Kompozit Numune Gir</button>\n <div *ngIf=\"compositeEditor\" class=\"print-exclude\"><div class=\"row\"><div class=\"col-md-3 mb-2\" *ngFor=\"let p of parameters\"><label>{{ p.name }}</label><input *ngIf=\"p.valueType === 'Number'\" type=\"number\" class=\"form-control\" [(ngModel)]=\"measurement(p, true).number\" (ngModelChange)=\"changed(true)\" [disabled]=\"p.calculated || busy\" /><select *ngIf=\"p.valueType === 'Choice'\" class=\"form-control\" [(ngModel)]=\"measurement(p, true).text\" (change)=\"changed(true)\"><option value=\"\"></option><option *ngFor=\"let option of p.options\" [value]=\"option\">{{ option }}</option></select><input *ngIf=\"p.valueType === 'Text'\" class=\"form-control\" [(ngModel)]=\"measurement(p, true).text\" /></div></div><button class=\"btn btn-primary\" (click)=\"saveComposite()\" [disabled]=\"busy\">Numuneyi Kaydet</button><button class=\"btn btn-secondary ml-2\" (click)=\"compositeEditor = false\">Vazge\u00E7</button></div>\n </div>\n </div></div>\n <div class=\"card\"><div class=\"card-body\"><h5>De\u011Ferlendirme</h5><div class=\"row\">\n <div class=\"col-md-3\"><label>Genel De\u011Ferlendirme</label><select class=\"form-control\" [(ngModel)]=\"decision\" [attr.data-print-value]=\"statusLabel(decision || (f.inspection.revision ? f.inspection.status : 'Waiting'))\" [disabled]=\"!editable || busy\"><option value=\"\">Se\u00E7in</option><option *ngIf=\"allowed('Accept')\" value=\"Accepted\">Kabul</option><option *ngIf=\"allowed('Reject')\" value=\"Rejected\">Ret</option></select></div>\n <div class=\"col-md-3\"><label>Analizi Yapan *</label><input class=\"form-control\" [(ngModel)]=\"f.inspection.analyst\" [disabled]=\"!editable || busy\" /></div>\n <div class=\"col-md-3\"><label>Kontrol Tarihi / Saati *</label><input type=\"datetime-local\" class=\"form-control\" [(ngModel)]=\"f.inspection.inspectedAt\" (change)=\"changed()\" [disabled]=\"!editable || busy\" /></div>\n <div class=\"col-md-3\"><label>Miktar (kg)</label><input class=\"form-control\" [value]=\"f.inspection.quantityKg == null ? 'Tart\u0131m sonras\u0131 gelir' : f.inspection.quantityKg\" disabled /></div>\n <div class=\"col-md-4 mt-3\"><label>Tank No</label><select class=\"form-control\" [(ngModel)]=\"f.inspection.tankCode\" [disabled]=\"!editable || busy\"><option value=\"\">Se\u00E7in</option><option *ngFor=\"let tank of tanks\" [value]=\"tank.code\">{{ tank.name }}</option></select></div>\n <div class=\"col-md-4 mt-3\"><label>Ya\u011F Cinsi</label><select class=\"form-control\" [(ngModel)]=\"f.inspection.oilType\" (change)=\"changed()\" [disabled]=\"!editable || busy\"><option value=\"\">Se\u00E7in</option><option>Ay\u00E7i\u00E7ek</option><option>Rafine Ay\u00E7i\u00E7ek</option><option>Palm Oil</option><option>Palm Olein</option></select></div>\n <div class=\"col-md-12 mt-3\"><label>A\u00E7\u0131klama / Di\u011Fer <span *ngIf=\"decision === 'Rejected'\">*</span></label><textarea rows=\"3\" class=\"form-control\" [(ngModel)]=\"f.inspection.notes\" [disabled]=\"!editable || busy\"></textarea></div>\n </div><div *ngIf=\"validationError\" class=\"alert alert-danger mt-3 mb-2\" role=\"alert\">{{ validationError }}</div><div class=\"mt-3\"><button *ngIf=\"editable\" class=\"btn btn-outline-primary mr-2\" (click)=\"save(false)\" [disabled]=\"busy || !parameters.length\">Kaydet</button><button *ngIf=\"editable && (allowed('Accept') || allowed('Reject'))\" class=\"btn btn-primary mr-2\" (click)=\"save(true)\" [disabled]=\"busy || !parameters.length\">Kaydet ve Onayla</button><button *ngIf=\"allowed('Print')\" class=\"btn btn-outline-secondary mr-2\" (click)=\"print()\" [disabled]=\"busy || !f.inspection.revision\">Formu Yazd\u0131r</button><button class=\"btn btn-secondary\" (click)=\"back()\">Vazge\u00E7</button></div>\n <p *ngIf=\"!f.canEdit\" class=\"text-muted mt-3\">Ara\u00E7 tart\u0131ma girdi\u011Fi, \u00E7\u0131kt\u0131\u011F\u0131 veya iptal edildi\u011Fi i\u00E7in kay\u0131t salt okunur.</p>\n </div></div>\n </ng-container>\n</div>\n", styles: [".quality-loading{padding:1.5rem;text-align:center;color:#5b526c}.print-only{display:none}.quality-status{display:inline-flex;align-items:center;gap:.5rem;padding:.55rem .85rem;border:1px solid transparent;border-radius:.4rem;font-size:.9375rem;font-weight:600;line-height:1.4}.quality-status-accepted{color:#166534;background:#dcfce7;border-color:#86efac}.quality-status-rejected{color:#991b1b;background:#fee2e2;border-color:#fca5a5}.quality-status-draft{color:#1e40af;background:#dbeafe;border-color:#93c5fd}.quality-status-waiting{color:#854d0e;background:#fef3c7;border-color:#fcd34d}.vehicle-table{min-width:1950px;white-space:nowrap}.actions{min-width:130px}.quality-questions-link{display:inline-flex;align-items:center;min-height:calc(1.5em + .5rem + 2px);margin-left:.4rem;padding:.25rem .5rem;color:#9a5a00;background:#fff3d6;border:1px solid #edb85b;border-radius:.2rem;font-size:.875rem;line-height:1.5;text-decoration:none}.quality-questions-link:hover,.quality-questions-link:focus{color:#fff;background:#b86b00;border-color:#b86b00;text-decoration:none}.intake-actions-cell{display:flex;align-items:center}:host ::ng-deep .intake-grid .dx-data-row>td{vertical-align:middle}.intake-actions-toggle{display:inline-flex;align-items:center;gap:.5rem;padding:.3rem .65rem;font-family:inherit;font-size:.8125rem;line-height:1.3}.intake-action-menu{min-width:210px;margin-top:.35rem;padding:.3rem;background:#fff;border:1px solid #dee2e6;border-radius:.375rem;box-shadow:0 .25rem .75rem #0000001a}.intake-action-menu .dropdown-item{display:block;text-align:left;border:0;border-radius:.25rem;background:none;color:#343a40;padding:.5rem .65rem;font-family:inherit;font-size:.8125rem;font-weight:400;line-height:1.4;text-decoration:none;white-space:nowrap;cursor:pointer}.intake-action-menu .dropdown-item:hover,.intake-action-menu .dropdown-item:focus-visible{background:#eef2ff;color:#2446b5}.page-size{width:85px}.vehicle-info{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1rem;margin:1rem 0}.vehicle-info label{font-size:.8rem;color:#6c757d;margin-bottom:.2rem}.vehicle-info p{background:#f5f3f8;padding:.55rem;min-height:2.5rem;overflow-wrap:anywhere}.measurement-table{min-width:700px}.measurement-table th{background:#f2edf7}.measurement-table td{vertical-align:middle}.out-of-limit,.rejected-row{background:#ffe6e9!important}.out-of-limit input,.out-of-limit select{border-color:#dc3545}@media (max-width: 900px){.vehicle-info{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width: 550px){.vehicle-info{grid-template-columns:1fr}}\n"] }]
|
|
1149
|
+
}], ctorParameters: function () { return [{ type: QualityApiService }, { type: i2$1.ActivatedRoute }, { type: i2$1.Router }, { type: i2.PermissionService }]; }, propDecorators: { printArea: [{
|
|
1150
|
+
type: ViewChild,
|
|
1151
|
+
args: ['printArea']
|
|
1152
|
+
}] } });
|
|
1153
|
+
|
|
1154
|
+
class QualityDefinitionsComponent {
|
|
1155
|
+
constructor(api, permissions) {
|
|
1156
|
+
this.api = api;
|
|
1157
|
+
this.permissions = permissions;
|
|
1158
|
+
this.tab = 'details';
|
|
1159
|
+
this.types = [];
|
|
1160
|
+
this.details = [];
|
|
1161
|
+
this.tanks = [];
|
|
1162
|
+
this.shifts = [];
|
|
1163
|
+
this.detail = null;
|
|
1164
|
+
this.tank = null;
|
|
1165
|
+
this.shift = null;
|
|
1166
|
+
this.isNew = true;
|
|
1167
|
+
this.busy = false;
|
|
1168
|
+
this.error = '';
|
|
1169
|
+
this.modalError = '';
|
|
1170
|
+
this.success = '';
|
|
1171
|
+
this.laborants = [];
|
|
1172
|
+
this.laborantsBusy = false;
|
|
1173
|
+
this.laborantsError = '';
|
|
1174
|
+
this.profiles = [{ code: '', name: 'Soruları kendim tanımlayacağım' }, { code: 'RAW', name: 'Ham Ayçiçek Yağı' }, { code: 'REFINED', name: 'Rafine Yağ' }, { code: 'PALM', name: 'Palm Oil / Palm Olein' }, { code: 'COAL', name: 'Kömür' }, { code: 'NAOH', name: 'Kostik (NaOH)' }, { code: 'PHOSPHORIC', name: 'Fosforik Asit' }, { code: 'SULFURIC', name: 'Sülfürik Asit' }, { code: 'PERLITE', name: 'Perlit' }, { code: 'EARTH', name: 'Ağartma Toprağı' }];
|
|
1175
|
+
}
|
|
1176
|
+
get canEdit() { return this.permissions.getGrantedPolicy('Kalite.Definitions.Edit'); }
|
|
1177
|
+
get canDelete() { return this.permissions.getGrantedPolicy('Kalite.Definitions.Delete'); }
|
|
1178
|
+
ngOnInit() { this.load(); }
|
|
1179
|
+
load() {
|
|
1180
|
+
this.busy = true;
|
|
1181
|
+
this.error = '';
|
|
1182
|
+
if (this.tab === 'details') {
|
|
1183
|
+
this.api.movementTypes().subscribe({ next: x => this.types = x, error: e => this.error = errorMessage(e) });
|
|
1184
|
+
this.api.movementDetails().subscribe({ next: x => { this.details = x; this.busy = false; }, error: e => { this.error = errorMessage(e); this.busy = false; } });
|
|
1185
|
+
}
|
|
1186
|
+
else if (this.tab === 'tanks')
|
|
1187
|
+
this.api.tanks().subscribe({ next: x => { this.tanks = x; this.busy = false; }, error: e => { this.error = errorMessage(e); this.busy = false; } });
|
|
1188
|
+
else
|
|
1189
|
+
this.api.shifts().subscribe({ next: x => { this.shifts = x; this.busy = false; }, error: e => { this.error = errorMessage(e); this.busy = false; } });
|
|
1190
|
+
}
|
|
1191
|
+
selectTab(tab) { this.tab = tab; this.close(); this.load(); }
|
|
1192
|
+
name(code) { var _a; return ((_a = this.types.find(x => x.code === code)) === null || _a === void 0 ? void 0 : _a.name) || code; }
|
|
1193
|
+
openDetail(value) { this.error = ''; this.modalError = ''; this.isNew = !value; this.detail = value ? Object.assign({}, value) : { code: '', movementTypeCode: '', detailCode: '', name: '', profile: '', active: true }; }
|
|
1194
|
+
openTank(value) { this.error = ''; this.modalError = ''; this.isNew = !value; this.tank = value ? Object.assign({}, value) : { code: '', name: '', type: 'Raw', capacity: null, active: true }; }
|
|
1195
|
+
openShift(value) {
|
|
1196
|
+
this.error = '';
|
|
1197
|
+
this.modalError = '';
|
|
1198
|
+
this.isNew = !value;
|
|
1199
|
+
this.shift = value ? Object.assign(Object.assign({}, value), { analystUserId: value.analystUserId || null }) : { code: '', name: '', startHour: 7, endHour: 15, analyst: '', analystUserId: null, active: true };
|
|
1200
|
+
this.laborants = [];
|
|
1201
|
+
this.laborantsBusy = true;
|
|
1202
|
+
this.laborantsError = '';
|
|
1203
|
+
this.api.laborants().subscribe({ next: x => { this.laborants = x; this.laborantsBusy = false; },
|
|
1204
|
+
error: e => { this.laborantsError = errorMessage(e); this.laborantsBusy = false; } });
|
|
1205
|
+
}
|
|
1206
|
+
laborantChanged() {
|
|
1207
|
+
var _a;
|
|
1208
|
+
if (this.shift)
|
|
1209
|
+
this.shift.analyst = ((_a = this.laborants.find(x => x.id === this.shift.analystUserId)) === null || _a === void 0 ? void 0 : _a.userName) || '';
|
|
1210
|
+
}
|
|
1211
|
+
get selectedLaborantMissing() { var _a; return !!((_a = this.shift) === null || _a === void 0 ? void 0 : _a.analystUserId) && !this.laborants.some(x => x.id === this.shift.analystUserId); }
|
|
1212
|
+
close() { this.detail = null; this.tank = null; this.shift = null; this.modalError = ''; }
|
|
1213
|
+
save() {
|
|
1214
|
+
const value = this.detail || this.tank || this.shift;
|
|
1215
|
+
if (!value)
|
|
1216
|
+
return;
|
|
1217
|
+
value.code = this.isNew ? value.code.trim().toUpperCase() : value.code;
|
|
1218
|
+
this.busy = true;
|
|
1219
|
+
this.modalError = '';
|
|
1220
|
+
const request = this.detail ? this.api.saveDetail(this.detail, this.isNew) : this.tank ? this.api.saveTank(this.tank, this.isNew) : this.api.saveShift(this.shift);
|
|
1221
|
+
request.subscribe({ next: () => { this.close(); this.success = 'Tanım kaydedildi.'; this.load(); }, error: e => { this.modalError = errorMessage(e); this.busy = false; } });
|
|
1222
|
+
}
|
|
1223
|
+
delete() {
|
|
1224
|
+
const value = this.detail || this.tank || this.shift;
|
|
1225
|
+
if (!value || this.isNew || this.busy)
|
|
1226
|
+
return;
|
|
1227
|
+
const type = this.detail ? 'araç hareket türü detayını' : this.tank ? 'tankı' : 'vardiyayı';
|
|
1228
|
+
if (!confirm(`${value.code} kodlu ${type} ve bağlı tanımları kalıcı olarak silinsin mi?`))
|
|
1229
|
+
return;
|
|
1230
|
+
this.busy = true;
|
|
1231
|
+
this.modalError = '';
|
|
1232
|
+
const request = this.detail ? this.api.deleteDetail(value.code) : this.tank ? this.api.deleteTank(value.code) : this.api.deleteShift(value.code);
|
|
1233
|
+
request.subscribe({ next: () => { this.close(); this.success = 'Tanım silindi.'; this.load(); }, error: e => { this.modalError = errorMessage(e); this.busy = false; } });
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
QualityDefinitionsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: QualityDefinitionsComponent, deps: [{ token: QualityApiService }, { token: i2.PermissionService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1237
|
+
QualityDefinitionsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: QualityDefinitionsComponent, selector: "lib-quality-definitions", ngImport: i0, template: "<div class=\"container-fluid\"><h3>Kalite Tan\u0131mlar\u0131</h3><div class=\"card\"><div class=\"card-body\">\n <div class=\"d-flex justify-content-between mb-3\"><div class=\"btn-group\">\n <button class=\"btn\" [class.btn-primary]=\"tab === 'details'\" [class.btn-outline-secondary]=\"tab !== 'details'\" (click)=\"selectTab('details')\">Ara\u00E7 Hareket T\u00FCrleri Detay</button>\n <button class=\"btn\" [class.btn-primary]=\"tab === 'tanks'\" [class.btn-outline-secondary]=\"tab !== 'tanks'\" (click)=\"selectTab('tanks')\">Tanklar</button>\n <button class=\"btn\" [class.btn-primary]=\"tab === 'shifts'\" [class.btn-outline-secondary]=\"tab !== 'shifts'\" (click)=\"selectTab('shifts')\">Vardiyalar</button>\n </div><button class=\"btn btn-primary\" *ngIf=\"canEdit\" [disabled]=\"busy\" (click)=\"tab === 'details' ? openDetail() : tab === 'tanks' ? openTank() : openShift()\">+ Yeni Kay\u0131t</button></div>\n <div *ngIf=\"error\" class=\"alert alert-danger\">{{ error }}</div><div *ngIf=\"success\" class=\"alert alert-success\">{{ success }}</div><div *ngIf=\"busy\" class=\"quality-loading\" role=\"status\">Tan\u0131mlar y\u00FCkleniyor\u2026</div>\n <div class=\"table-responsive\" [hidden]=\"busy\">\n <table *ngIf=\"tab === 'details'\" class=\"table table-striped table-bordered\"><thead><tr><th>\u0130\u015Flemler</th><th>Ara\u00E7 Hareket T\u00FCr\u00FC</th><th>Detay Kodu</th><th>Detay Ad\u0131</th><th>Aktif</th></tr></thead><tbody><tr *ngFor=\"let d of details\"><td><button *ngIf=\"canEdit\" class=\"btn btn-sm btn-outline-primary\" (click)=\"openDetail(d)\">D\u00FCzenle</button><a class=\"quality-questions-link\" [routerLink]=\"['/kalite/parameters']\" [queryParams]=\"{type: 'Input', detail: d.code}\">Kalite Sorular\u0131</a></td><td>{{ name(d.movementTypeCode) }}</td><td>{{ d.detailCode || '\u2014' }}</td><td>{{ d.name || '\u2014' }}</td><td>{{ d.active ? 'Evet' : 'Hay\u0131r' }}</td></tr></tbody></table>\n <table *ngIf=\"tab === 'tanks'\" class=\"table table-striped table-bordered\"><thead><tr><th>\u0130\u015Flemler</th><th>Kod</th><th>Ad</th><th>Tip</th><th>Kapasite</th><th>Aktif</th></tr></thead><tbody><tr *ngFor=\"let t of tanks\"><td><button *ngIf=\"canEdit\" class=\"btn btn-sm btn-outline-primary\" (click)=\"openTank(t)\">D\u00FCzenle</button></td><td>{{ t.code }}</td><td>{{ t.name }}</td><td>{{ t.type === 'Raw' ? 'Ham Ya\u011F' : t.type === 'Refined' ? 'Rafine' : t.type === 'Product' ? '\u00DCr\u00FCn' : 'Ara' }}</td><td>{{ t.capacity }}</td><td>{{ t.active ? 'Evet' : 'Hay\u0131r' }}</td></tr></tbody></table>\n <table *ngIf=\"tab === 'shifts'\" class=\"table table-striped table-bordered\"><thead><tr><th>\u0130\u015Flemler</th><th>Kod</th><th>Ad</th><th>Ba\u015Flang\u0131\u00E7</th><th>Biti\u015F</th><th>Laborant</th><th>Aktif</th></tr></thead><tbody><tr *ngFor=\"let s of shifts\"><td><button *ngIf=\"canEdit\" class=\"btn btn-sm btn-outline-primary\" (click)=\"openShift(s)\">D\u00FCzenle</button></td><td>{{ s.code }}</td><td>{{ s.name }}</td><td>{{ s.startHour | number:'2.0-0' }}:00</td><td>{{ s.endHour | number:'2.0-0' }}:00</td><td>{{ s.analyst }}</td><td>{{ s.active ? 'Evet' : 'Hay\u0131r' }}</td></tr></tbody></table>\n </div><p *ngIf=\"tab === 'details'\" class=\"text-muted\">Etkin tan\u0131mlarda bulunan ara\u00E7 hareket t\u00FCrleri kalite kontrole tabidir. Detay kodu ve ad\u0131 bo\u015F b\u0131rak\u0131larak yaln\u0131z hareket t\u00FCr\u00FC ba\u015Fl\u0131\u011F\u0131 tan\u0131mlanabilir.</p>\n</div></div></div>\n<abp-modal [visible]=\"!!(detail || tank || shift)\" (visibleChange)=\"!$event && close()\" [busy]=\"busy\" [options]=\"{size: 'lg'}\">\n <ng-template #abpHeader><h5>{{ isNew ? 'Yeni Tan\u0131m' : 'Tan\u0131m\u0131 D\u00FCzenle' }}</h5></ng-template>\n <ng-template #abpBody><div *ngIf=\"modalError\" class=\"alert alert-danger\">{{ modalError }}</div>\n <div *ngIf=\"detail as d\" class=\"row\">\n <div class=\"col-md-4\"><label>Kay\u0131t Kodu *</label><input class=\"form-control\" [(ngModel)]=\"d.code\" [disabled]=\"!isNew\" maxlength=\"24\" /></div><div class=\"col-md-8\"><label>Ara\u00E7 Hareket T\u00FCr\u00FC *</label><select class=\"form-control\" [(ngModel)]=\"d.movementTypeCode\" [disabled]=\"!isNew\"><option value=\"\">Se\u00E7in</option><option *ngFor=\"let type of types\" [value]=\"type.code\">{{ type.name }}</option></select></div>\n <div class=\"col-md-4 mt-3\"><label>Detay Kodu</label><input class=\"form-control\" [(ngModel)]=\"d.detailCode\" /></div><div class=\"col-md-8 mt-3\"><label>Detay Ad\u0131</label><input class=\"form-control\" [(ngModel)]=\"d.name\" /></div>\n <div class=\"col-md-12 mt-3\"><label>Ba\u015Flang\u0131\u00E7 Sorular\u0131</label><select class=\"form-control\" [(ngModel)]=\"d.profile\" [disabled]=\"!isNew\"><option *ngFor=\"let p of profiles\" [value]=\"p.code\">{{ p.name }}</option></select><small class=\"text-muted\">Se\u00E7ilen \u015Fablonun sorular\u0131 ve limitleri Kalite Parametreleri ekran\u0131ndan d\u00FCzenlenebilir.</small></div><div class=\"col-md-12 mt-3\"><label><input type=\"checkbox\" [(ngModel)]=\"d.active\" /> Aktif</label></div>\n </div>\n <div *ngIf=\"tank as t\" class=\"row\"><div class=\"col-md-4\"><label>Kod *</label><input class=\"form-control\" [(ngModel)]=\"t.code\" [disabled]=\"!isNew\" /></div><div class=\"col-md-8\"><label>Ad *</label><input class=\"form-control\" [(ngModel)]=\"t.name\" /></div><div class=\"col-md-6 mt-3\"><label>Tip</label><select class=\"form-control\" [(ngModel)]=\"t.type\"><option value=\"Raw\">Ham Ya\u011F</option><option value=\"Refined\">Rafine</option><option value=\"Intermediate\">Ara</option><option value=\"Product\">\u00DCr\u00FCn</option></select></div><div class=\"col-md-6 mt-3\"><label>Kapasite</label><input type=\"number\" min=\"0\" class=\"form-control\" [(ngModel)]=\"t.capacity\" /></div><div class=\"col-md-12 mt-3\"><label><input type=\"checkbox\" [(ngModel)]=\"t.active\" /> Aktif</label></div></div>\n <div *ngIf=\"shift as s\" class=\"row\">\n <div class=\"col-md-3\"><label>Kod *</label><input class=\"form-control\" [(ngModel)]=\"s.code\" [disabled]=\"!isNew\" /></div>\n <div class=\"col-md-9\"><label>Ad *</label><input class=\"form-control\" [(ngModel)]=\"s.name\" /></div>\n <div class=\"col-md-4 mt-3\"><label>Ba\u015Flang\u0131\u00E7 Saati</label><input type=\"number\" min=\"0\" max=\"23\" class=\"form-control\" [(ngModel)]=\"s.startHour\" /></div>\n <div class=\"col-md-4 mt-3\"><label>Biti\u015F Saati</label><input type=\"number\" min=\"0\" max=\"23\" class=\"form-control\" [(ngModel)]=\"s.endHour\" /></div>\n <div class=\"col-md-4 mt-3\"><label>Laborant</label>\n <select class=\"form-control\" [(ngModel)]=\"s.analystUserId\" (change)=\"laborantChanged()\" [disabled]=\"busy || laborantsBusy\">\n <option [ngValue]=\"null\">{{ !s.analystUserId && s.analyst ? 'Mevcut: ' + s.analyst + ' (eski kay\u0131t)' : 'Se\u00E7in' }}</option>\n <option *ngIf=\"selectedLaborantMissing\" [ngValue]=\"s.analystUserId\" disabled>{{ s.analyst }} (se\u00E7ilebilir de\u011Fil)</option>\n <option *ngFor=\"let user of laborants\" [ngValue]=\"user.id\">{{ user.userName }}</option>\n </select>\n <small *ngIf=\"laborantsBusy\" class=\"text-muted\">Kullan\u0131c\u0131lar y\u00FCkleniyor\u2026</small>\n <small *ngIf=\"!laborantsBusy && !laborantsError && !laborants.length\" class=\"text-muted\">Bu firmada aktif ve proses veri giri\u015Fi yetkisi olan kullan\u0131c\u0131 bulunamad\u0131.</small>\n <div *ngIf=\"laborantsError\" class=\"text-danger\" role=\"alert\">{{ laborantsError }}</div>\n </div>\n <div class=\"col-md-12 mt-3\"><label><input type=\"checkbox\" [(ngModel)]=\"s.active\" /> Aktif</label></div>\n </div>\n </ng-template><ng-template #abpFooter><button class=\"btn btn-danger mr-auto\" *ngIf=\"canDelete && !isNew\" [disabled]=\"busy\" (click)=\"delete()\">Sil</button><button class=\"btn btn-secondary\" [disabled]=\"busy\" (click)=\"close()\">Vazge\u00E7</button><button class=\"btn btn-primary\" [disabled]=\"busy\" (click)=\"save()\">Kaydet</button></ng-template>\n</abp-modal>\n", styles: [".quality-loading{padding:1.5rem;text-align:center;color:#5b526c}.print-only{display:none}.quality-status{display:inline-flex;align-items:center;gap:.5rem;padding:.55rem .85rem;border:1px solid transparent;border-radius:.4rem;font-size:.9375rem;font-weight:600;line-height:1.4}.quality-status-accepted{color:#166534;background:#dcfce7;border-color:#86efac}.quality-status-rejected{color:#991b1b;background:#fee2e2;border-color:#fca5a5}.quality-status-draft{color:#1e40af;background:#dbeafe;border-color:#93c5fd}.quality-status-waiting{color:#854d0e;background:#fef3c7;border-color:#fcd34d}.vehicle-table{min-width:1950px;white-space:nowrap}.actions{min-width:130px}.quality-questions-link{display:inline-flex;align-items:center;min-height:calc(1.5em + .5rem + 2px);margin-left:.4rem;padding:.25rem .5rem;color:#9a5a00;background:#fff3d6;border:1px solid #edb85b;border-radius:.2rem;font-size:.875rem;line-height:1.5;text-decoration:none}.quality-questions-link:hover,.quality-questions-link:focus{color:#fff;background:#b86b00;border-color:#b86b00;text-decoration:none}.intake-actions-cell{display:flex;align-items:center}:host ::ng-deep .intake-grid .dx-data-row>td{vertical-align:middle}.intake-actions-toggle{display:inline-flex;align-items:center;gap:.5rem;padding:.3rem .65rem;font-family:inherit;font-size:.8125rem;line-height:1.3}.intake-action-menu{min-width:210px;margin-top:.35rem;padding:.3rem;background:#fff;border:1px solid #dee2e6;border-radius:.375rem;box-shadow:0 .25rem .75rem #0000001a}.intake-action-menu .dropdown-item{display:block;text-align:left;border:0;border-radius:.25rem;background:none;color:#343a40;padding:.5rem .65rem;font-family:inherit;font-size:.8125rem;font-weight:400;line-height:1.4;text-decoration:none;white-space:nowrap;cursor:pointer}.intake-action-menu .dropdown-item:hover,.intake-action-menu .dropdown-item:focus-visible{background:#eef2ff;color:#2446b5}.page-size{width:85px}.vehicle-info{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1rem;margin:1rem 0}.vehicle-info label{font-size:.8rem;color:#6c757d;margin-bottom:.2rem}.vehicle-info p{background:#f5f3f8;padding:.55rem;min-height:2.5rem;overflow-wrap:anywhere}.measurement-table{min-width:700px}.measurement-table th{background:#f2edf7}.measurement-table td{vertical-align:middle}.out-of-limit,.rejected-row{background:#ffe6e9!important}.out-of-limit input,.out-of-limit select{border-color:#dc3545}@media (max-width: 900px){.vehicle-info{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width: 550px){.vehicle-info{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.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: i5.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i5.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i5.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i5.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2$1.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i6.ModalComponent, selector: "abp-modal", inputs: ["visible", "busy", "options", "suppressUnsavedChangesWarning"], outputs: ["visibleChange", "init", "appear", "disappear"] }, { kind: "pipe", type: i3.DecimalPipe, name: "number" }] });
|
|
1238
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: QualityDefinitionsComponent, decorators: [{
|
|
1239
|
+
type: Component,
|
|
1240
|
+
args: [{ selector: 'lib-quality-definitions', template: "<div class=\"container-fluid\"><h3>Kalite Tan\u0131mlar\u0131</h3><div class=\"card\"><div class=\"card-body\">\n <div class=\"d-flex justify-content-between mb-3\"><div class=\"btn-group\">\n <button class=\"btn\" [class.btn-primary]=\"tab === 'details'\" [class.btn-outline-secondary]=\"tab !== 'details'\" (click)=\"selectTab('details')\">Ara\u00E7 Hareket T\u00FCrleri Detay</button>\n <button class=\"btn\" [class.btn-primary]=\"tab === 'tanks'\" [class.btn-outline-secondary]=\"tab !== 'tanks'\" (click)=\"selectTab('tanks')\">Tanklar</button>\n <button class=\"btn\" [class.btn-primary]=\"tab === 'shifts'\" [class.btn-outline-secondary]=\"tab !== 'shifts'\" (click)=\"selectTab('shifts')\">Vardiyalar</button>\n </div><button class=\"btn btn-primary\" *ngIf=\"canEdit\" [disabled]=\"busy\" (click)=\"tab === 'details' ? openDetail() : tab === 'tanks' ? openTank() : openShift()\">+ Yeni Kay\u0131t</button></div>\n <div *ngIf=\"error\" class=\"alert alert-danger\">{{ error }}</div><div *ngIf=\"success\" class=\"alert alert-success\">{{ success }}</div><div *ngIf=\"busy\" class=\"quality-loading\" role=\"status\">Tan\u0131mlar y\u00FCkleniyor\u2026</div>\n <div class=\"table-responsive\" [hidden]=\"busy\">\n <table *ngIf=\"tab === 'details'\" class=\"table table-striped table-bordered\"><thead><tr><th>\u0130\u015Flemler</th><th>Ara\u00E7 Hareket T\u00FCr\u00FC</th><th>Detay Kodu</th><th>Detay Ad\u0131</th><th>Aktif</th></tr></thead><tbody><tr *ngFor=\"let d of details\"><td><button *ngIf=\"canEdit\" class=\"btn btn-sm btn-outline-primary\" (click)=\"openDetail(d)\">D\u00FCzenle</button><a class=\"quality-questions-link\" [routerLink]=\"['/kalite/parameters']\" [queryParams]=\"{type: 'Input', detail: d.code}\">Kalite Sorular\u0131</a></td><td>{{ name(d.movementTypeCode) }}</td><td>{{ d.detailCode || '\u2014' }}</td><td>{{ d.name || '\u2014' }}</td><td>{{ d.active ? 'Evet' : 'Hay\u0131r' }}</td></tr></tbody></table>\n <table *ngIf=\"tab === 'tanks'\" class=\"table table-striped table-bordered\"><thead><tr><th>\u0130\u015Flemler</th><th>Kod</th><th>Ad</th><th>Tip</th><th>Kapasite</th><th>Aktif</th></tr></thead><tbody><tr *ngFor=\"let t of tanks\"><td><button *ngIf=\"canEdit\" class=\"btn btn-sm btn-outline-primary\" (click)=\"openTank(t)\">D\u00FCzenle</button></td><td>{{ t.code }}</td><td>{{ t.name }}</td><td>{{ t.type === 'Raw' ? 'Ham Ya\u011F' : t.type === 'Refined' ? 'Rafine' : t.type === 'Product' ? '\u00DCr\u00FCn' : 'Ara' }}</td><td>{{ t.capacity }}</td><td>{{ t.active ? 'Evet' : 'Hay\u0131r' }}</td></tr></tbody></table>\n <table *ngIf=\"tab === 'shifts'\" class=\"table table-striped table-bordered\"><thead><tr><th>\u0130\u015Flemler</th><th>Kod</th><th>Ad</th><th>Ba\u015Flang\u0131\u00E7</th><th>Biti\u015F</th><th>Laborant</th><th>Aktif</th></tr></thead><tbody><tr *ngFor=\"let s of shifts\"><td><button *ngIf=\"canEdit\" class=\"btn btn-sm btn-outline-primary\" (click)=\"openShift(s)\">D\u00FCzenle</button></td><td>{{ s.code }}</td><td>{{ s.name }}</td><td>{{ s.startHour | number:'2.0-0' }}:00</td><td>{{ s.endHour | number:'2.0-0' }}:00</td><td>{{ s.analyst }}</td><td>{{ s.active ? 'Evet' : 'Hay\u0131r' }}</td></tr></tbody></table>\n </div><p *ngIf=\"tab === 'details'\" class=\"text-muted\">Etkin tan\u0131mlarda bulunan ara\u00E7 hareket t\u00FCrleri kalite kontrole tabidir. Detay kodu ve ad\u0131 bo\u015F b\u0131rak\u0131larak yaln\u0131z hareket t\u00FCr\u00FC ba\u015Fl\u0131\u011F\u0131 tan\u0131mlanabilir.</p>\n</div></div></div>\n<abp-modal [visible]=\"!!(detail || tank || shift)\" (visibleChange)=\"!$event && close()\" [busy]=\"busy\" [options]=\"{size: 'lg'}\">\n <ng-template #abpHeader><h5>{{ isNew ? 'Yeni Tan\u0131m' : 'Tan\u0131m\u0131 D\u00FCzenle' }}</h5></ng-template>\n <ng-template #abpBody><div *ngIf=\"modalError\" class=\"alert alert-danger\">{{ modalError }}</div>\n <div *ngIf=\"detail as d\" class=\"row\">\n <div class=\"col-md-4\"><label>Kay\u0131t Kodu *</label><input class=\"form-control\" [(ngModel)]=\"d.code\" [disabled]=\"!isNew\" maxlength=\"24\" /></div><div class=\"col-md-8\"><label>Ara\u00E7 Hareket T\u00FCr\u00FC *</label><select class=\"form-control\" [(ngModel)]=\"d.movementTypeCode\" [disabled]=\"!isNew\"><option value=\"\">Se\u00E7in</option><option *ngFor=\"let type of types\" [value]=\"type.code\">{{ type.name }}</option></select></div>\n <div class=\"col-md-4 mt-3\"><label>Detay Kodu</label><input class=\"form-control\" [(ngModel)]=\"d.detailCode\" /></div><div class=\"col-md-8 mt-3\"><label>Detay Ad\u0131</label><input class=\"form-control\" [(ngModel)]=\"d.name\" /></div>\n <div class=\"col-md-12 mt-3\"><label>Ba\u015Flang\u0131\u00E7 Sorular\u0131</label><select class=\"form-control\" [(ngModel)]=\"d.profile\" [disabled]=\"!isNew\"><option *ngFor=\"let p of profiles\" [value]=\"p.code\">{{ p.name }}</option></select><small class=\"text-muted\">Se\u00E7ilen \u015Fablonun sorular\u0131 ve limitleri Kalite Parametreleri ekran\u0131ndan d\u00FCzenlenebilir.</small></div><div class=\"col-md-12 mt-3\"><label><input type=\"checkbox\" [(ngModel)]=\"d.active\" /> Aktif</label></div>\n </div>\n <div *ngIf=\"tank as t\" class=\"row\"><div class=\"col-md-4\"><label>Kod *</label><input class=\"form-control\" [(ngModel)]=\"t.code\" [disabled]=\"!isNew\" /></div><div class=\"col-md-8\"><label>Ad *</label><input class=\"form-control\" [(ngModel)]=\"t.name\" /></div><div class=\"col-md-6 mt-3\"><label>Tip</label><select class=\"form-control\" [(ngModel)]=\"t.type\"><option value=\"Raw\">Ham Ya\u011F</option><option value=\"Refined\">Rafine</option><option value=\"Intermediate\">Ara</option><option value=\"Product\">\u00DCr\u00FCn</option></select></div><div class=\"col-md-6 mt-3\"><label>Kapasite</label><input type=\"number\" min=\"0\" class=\"form-control\" [(ngModel)]=\"t.capacity\" /></div><div class=\"col-md-12 mt-3\"><label><input type=\"checkbox\" [(ngModel)]=\"t.active\" /> Aktif</label></div></div>\n <div *ngIf=\"shift as s\" class=\"row\">\n <div class=\"col-md-3\"><label>Kod *</label><input class=\"form-control\" [(ngModel)]=\"s.code\" [disabled]=\"!isNew\" /></div>\n <div class=\"col-md-9\"><label>Ad *</label><input class=\"form-control\" [(ngModel)]=\"s.name\" /></div>\n <div class=\"col-md-4 mt-3\"><label>Ba\u015Flang\u0131\u00E7 Saati</label><input type=\"number\" min=\"0\" max=\"23\" class=\"form-control\" [(ngModel)]=\"s.startHour\" /></div>\n <div class=\"col-md-4 mt-3\"><label>Biti\u015F Saati</label><input type=\"number\" min=\"0\" max=\"23\" class=\"form-control\" [(ngModel)]=\"s.endHour\" /></div>\n <div class=\"col-md-4 mt-3\"><label>Laborant</label>\n <select class=\"form-control\" [(ngModel)]=\"s.analystUserId\" (change)=\"laborantChanged()\" [disabled]=\"busy || laborantsBusy\">\n <option [ngValue]=\"null\">{{ !s.analystUserId && s.analyst ? 'Mevcut: ' + s.analyst + ' (eski kay\u0131t)' : 'Se\u00E7in' }}</option>\n <option *ngIf=\"selectedLaborantMissing\" [ngValue]=\"s.analystUserId\" disabled>{{ s.analyst }} (se\u00E7ilebilir de\u011Fil)</option>\n <option *ngFor=\"let user of laborants\" [ngValue]=\"user.id\">{{ user.userName }}</option>\n </select>\n <small *ngIf=\"laborantsBusy\" class=\"text-muted\">Kullan\u0131c\u0131lar y\u00FCkleniyor\u2026</small>\n <small *ngIf=\"!laborantsBusy && !laborantsError && !laborants.length\" class=\"text-muted\">Bu firmada aktif ve proses veri giri\u015Fi yetkisi olan kullan\u0131c\u0131 bulunamad\u0131.</small>\n <div *ngIf=\"laborantsError\" class=\"text-danger\" role=\"alert\">{{ laborantsError }}</div>\n </div>\n <div class=\"col-md-12 mt-3\"><label><input type=\"checkbox\" [(ngModel)]=\"s.active\" /> Aktif</label></div>\n </div>\n </ng-template><ng-template #abpFooter><button class=\"btn btn-danger mr-auto\" *ngIf=\"canDelete && !isNew\" [disabled]=\"busy\" (click)=\"delete()\">Sil</button><button class=\"btn btn-secondary\" [disabled]=\"busy\" (click)=\"close()\">Vazge\u00E7</button><button class=\"btn btn-primary\" [disabled]=\"busy\" (click)=\"save()\">Kaydet</button></ng-template>\n</abp-modal>\n", styles: [".quality-loading{padding:1.5rem;text-align:center;color:#5b526c}.print-only{display:none}.quality-status{display:inline-flex;align-items:center;gap:.5rem;padding:.55rem .85rem;border:1px solid transparent;border-radius:.4rem;font-size:.9375rem;font-weight:600;line-height:1.4}.quality-status-accepted{color:#166534;background:#dcfce7;border-color:#86efac}.quality-status-rejected{color:#991b1b;background:#fee2e2;border-color:#fca5a5}.quality-status-draft{color:#1e40af;background:#dbeafe;border-color:#93c5fd}.quality-status-waiting{color:#854d0e;background:#fef3c7;border-color:#fcd34d}.vehicle-table{min-width:1950px;white-space:nowrap}.actions{min-width:130px}.quality-questions-link{display:inline-flex;align-items:center;min-height:calc(1.5em + .5rem + 2px);margin-left:.4rem;padding:.25rem .5rem;color:#9a5a00;background:#fff3d6;border:1px solid #edb85b;border-radius:.2rem;font-size:.875rem;line-height:1.5;text-decoration:none}.quality-questions-link:hover,.quality-questions-link:focus{color:#fff;background:#b86b00;border-color:#b86b00;text-decoration:none}.intake-actions-cell{display:flex;align-items:center}:host ::ng-deep .intake-grid .dx-data-row>td{vertical-align:middle}.intake-actions-toggle{display:inline-flex;align-items:center;gap:.5rem;padding:.3rem .65rem;font-family:inherit;font-size:.8125rem;line-height:1.3}.intake-action-menu{min-width:210px;margin-top:.35rem;padding:.3rem;background:#fff;border:1px solid #dee2e6;border-radius:.375rem;box-shadow:0 .25rem .75rem #0000001a}.intake-action-menu .dropdown-item{display:block;text-align:left;border:0;border-radius:.25rem;background:none;color:#343a40;padding:.5rem .65rem;font-family:inherit;font-size:.8125rem;font-weight:400;line-height:1.4;text-decoration:none;white-space:nowrap;cursor:pointer}.intake-action-menu .dropdown-item:hover,.intake-action-menu .dropdown-item:focus-visible{background:#eef2ff;color:#2446b5}.page-size{width:85px}.vehicle-info{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1rem;margin:1rem 0}.vehicle-info label{font-size:.8rem;color:#6c757d;margin-bottom:.2rem}.vehicle-info p{background:#f5f3f8;padding:.55rem;min-height:2.5rem;overflow-wrap:anywhere}.measurement-table{min-width:700px}.measurement-table th{background:#f2edf7}.measurement-table td{vertical-align:middle}.out-of-limit,.rejected-row{background:#ffe6e9!important}.out-of-limit input,.out-of-limit select{border-color:#dc3545}@media (max-width: 900px){.vehicle-info{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width: 550px){.vehicle-info{grid-template-columns:1fr}}\n"] }]
|
|
1241
|
+
}], ctorParameters: function () { return [{ type: QualityApiService }, { type: i2.PermissionService }]; } });
|
|
1242
|
+
|
|
1243
|
+
class QualityReportsComponent {
|
|
1244
|
+
constructor(api, route, permissions) {
|
|
1245
|
+
this.api = api;
|
|
1246
|
+
this.route = route;
|
|
1247
|
+
this.permissions = permissions;
|
|
1248
|
+
this.filter = { type: 'Input', from: localDate(new Date(new Date().getFullYear(), new Date().getMonth(), 1)), until: localDate(), groupBy: 'None' };
|
|
1249
|
+
this.report = null;
|
|
1250
|
+
this.forms = [];
|
|
1251
|
+
this.facilities = [];
|
|
1252
|
+
this.types = [];
|
|
1253
|
+
this.busy = false;
|
|
1254
|
+
this.error = '';
|
|
1255
|
+
this.statusLabel = statusLabel;
|
|
1256
|
+
}
|
|
1257
|
+
ngOnInit() {
|
|
1258
|
+
this.filter.type = this.route.snapshot.data['type'] || 'Input';
|
|
1259
|
+
this.api.reportForms().subscribe({ next: x => this.forms = x, error: e => this.error = errorMessage(e) });
|
|
1260
|
+
this.api.definitionFacilities().subscribe({ next: x => this.facilities = x, error: e => this.error = errorMessage(e) });
|
|
1261
|
+
this.api.qualityMovementTypes().subscribe({ next: x => this.types = x, error: e => this.error = errorMessage(e) });
|
|
1262
|
+
}
|
|
1263
|
+
get canExport() { return this.permissions.getGrantedPolicy('Kalite.Reports.Export'); }
|
|
1264
|
+
get visibleForms() { return this.forms.filter(x => (x.controlType || 'Process') === (this.filter.type === 'Process' ? 'Process' : 'Input')); }
|
|
1265
|
+
load() { this.busy = true; this.error = ''; this.api.report(this.filter).subscribe({ next: x => { this.report = x; this.busy = false; }, error: e => { this.error = errorMessage(e); this.busy = false; } }); }
|
|
1266
|
+
measurement(row, p) { return row.measurements.find(x => x.parameterCode === p.code); }
|
|
1267
|
+
pdf() { this.api.reportPdf(this.filter).subscribe({ next: b => download(b, `Kalite-${this.filter.type}-${this.filter.from}.pdf`), error: e => this.error = errorMessage(e) }); }
|
|
1268
|
+
excel() {
|
|
1269
|
+
this.busy = true;
|
|
1270
|
+
this.error = '';
|
|
1271
|
+
this.api.report(this.filter, true).subscribe({ next: (report) => __awaiter(this, void 0, void 0, function* () {
|
|
1272
|
+
try {
|
|
1273
|
+
const { Workbook } = yield import('exceljs');
|
|
1274
|
+
const workbook = new Workbook();
|
|
1275
|
+
workbook.creator = 'Kalite';
|
|
1276
|
+
let index = 0;
|
|
1277
|
+
if (report.type === 'Rejected') {
|
|
1278
|
+
const summary = workbook.addWorksheet('Ret Özeti');
|
|
1279
|
+
summary.addRow(['Grup', 'Toplam Kayıt', 'Ret Adedi', 'Ret Oranı (%)']);
|
|
1280
|
+
report.rejectionSummary.forEach(g => summary.addRow([g.groupName, g.total, g.rejected, g.rate]));
|
|
1281
|
+
summary.columns.forEach(c => c.width = 25);
|
|
1282
|
+
}
|
|
1283
|
+
for (const section of report.sections) {
|
|
1284
|
+
const sheet = workbook.addWorksheet(`Form ${++index}`);
|
|
1285
|
+
sheet.addRow([section.form.name]);
|
|
1286
|
+
sheet.addRow(['Doküman', section.form.documentCode, 'Yayın', section.form.publicationDate.slice(0, 10), 'Revizyon', section.form.revisionDate.slice(0, 10), section.form.revisionNumber]);
|
|
1287
|
+
sheet.addRow([section.groupName]);
|
|
1288
|
+
const divisor = section.form.quantityUnit === 't' ? 1000 : 1;
|
|
1289
|
+
const fixed = ['Tarih / Saat', 'Plaka', 'Dorse', 'Muhatap', 'Gemi', 'Hareket Türü', 'Detay', 'Menşei', 'Stok Nakli', 'Tank', 'Aktarılan Tank', 'Yağ Cinsi', `Miktar (${section.form.quantityUnit || 'kg'})`, 'Kalite Durumu', 'Analizi Yapan', 'Açıklama'];
|
|
1290
|
+
const header = sheet.addRow([...fixed, ...section.columns.map(p => p.name + (p.unit ? ` (${p.unit})` : ''))]);
|
|
1291
|
+
header.font = { bold: true };
|
|
1292
|
+
header.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFE8E1EF' } };
|
|
1293
|
+
for (const row of section.rows) {
|
|
1294
|
+
const excelRow = sheet.addRow([new Date(row.date), row.composite ? 'Gemi Kompozit Numunesi' : row.plate, row.trailerPlate,
|
|
1295
|
+
row.partner, row.ship, row.movementType, row.detail, row.origin === 'Imported' ? 'İthal' : row.origin === 'Domestic' ? 'İç Piyasa' : '',
|
|
1296
|
+
row.stockTransfer, row.tank, row.outputTank, row.oilType, row.quantityKg == null ? null : row.quantityKg / divisor, statusLabel(row.status), row.analyst, row.notes,
|
|
1297
|
+
...section.columns.map(p => { var _a, _b; const m = this.measurement(row, p); return (_b = (_a = m === null || m === void 0 ? void 0 : m.number) !== null && _a !== void 0 ? _a : m === null || m === void 0 ? void 0 : m.text) !== null && _b !== void 0 ? _b : ''; })]);
|
|
1298
|
+
excelRow.getCell(1).numFmt = 'dd.mm.yyyy hh:mm';
|
|
1299
|
+
excelRow.getCell(13).numFmt = '#,##0.00';
|
|
1300
|
+
if (row.status === 'Rejected')
|
|
1301
|
+
excelRow.eachCell(c => c.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFFFE1E6' } });
|
|
1302
|
+
section.columns.forEach((p, i) => {
|
|
1303
|
+
var _a;
|
|
1304
|
+
const cell = excelRow.getCell(fixed.length + i + 1);
|
|
1305
|
+
cell.numFmt = p.decimalPlaces ? '0.' + '0'.repeat(p.decimalPlaces) : '0';
|
|
1306
|
+
if ((_a = this.measurement(row, p)) === null || _a === void 0 ? void 0 : _a.outOfLimit)
|
|
1307
|
+
cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFFFAAAA' } };
|
|
1308
|
+
});
|
|
1309
|
+
}
|
|
1310
|
+
const totals = Array(fixed.length).fill(null);
|
|
1311
|
+
totals[0] = 'ORTALAMA';
|
|
1312
|
+
totals[1] = section.averageMode === 'Weighted' ? 'Miktar ağırlıklı' : 'Aritmetik';
|
|
1313
|
+
totals[12] = section.totalKg / divisor;
|
|
1314
|
+
sheet.addRow([...totals, ...section.columns.map(p => { var _a; return (_a = section.averages[p.code]) !== null && _a !== void 0 ? _a : null; })]).font = { bold: true };
|
|
1315
|
+
sheet.addRow(['Analizi Yapan / Kontrol Eden', ...Array.from(new Set(section.rows.map(r => r.analyst).filter(Boolean)))]);
|
|
1316
|
+
if (section.form.documentCode === 'FR.85')
|
|
1317
|
+
sheet.addRow(['KABUL', '', 'RED', '', 'ŞARTLI KABUL', '']);
|
|
1318
|
+
sheet.columns.forEach(c => { c.width = 20; c.alignment = { vertical: 'middle', wrapText: true }; });
|
|
1319
|
+
sheet.views = [{ state: 'frozen', ySplit: 4, xSplit: 2 }];
|
|
1320
|
+
sheet.pageSetup = { orientation: 'landscape', paperSize: 8, fitToPage: true, fitToWidth: 1, fitToHeight: 0 };
|
|
1321
|
+
}
|
|
1322
|
+
if (!workbook.worksheets.length)
|
|
1323
|
+
workbook.addWorksheet('Kayıt Yok').addRow(['Seçilen filtrelerde kayıt bulunamadı.']);
|
|
1324
|
+
const data = yield workbook.xlsx.writeBuffer();
|
|
1325
|
+
download(new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }), `Kalite-${report.type}-${this.filter.from}.xlsx`);
|
|
1326
|
+
}
|
|
1327
|
+
catch (e) {
|
|
1328
|
+
this.error = errorMessage(e);
|
|
1329
|
+
}
|
|
1330
|
+
finally {
|
|
1331
|
+
this.busy = false;
|
|
1332
|
+
}
|
|
1333
|
+
}), error: e => { this.error = errorMessage(e); this.busy = false; } });
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
QualityReportsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: QualityReportsComponent, deps: [{ token: QualityApiService }, { token: i2$1.ActivatedRoute }, { token: i2.PermissionService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1337
|
+
QualityReportsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: QualityReportsComponent, selector: "lib-quality-reports", ngImport: i0, template: "<div class=\"container-fluid\"><h3>{{ filter.type === 'Process' ? 'Rafineri Proses Analiz Raporu' : filter.type === 'Rejected' ? 'Kalite Kontrol Ret Raporu' : 'Girdi Kontrol Raporlar\u0131' }}</h3>\r\n <div class=\"card\"><div class=\"card-body\"><div class=\"row\">\r\n <div class=\"col-md-3\"><label>Ba\u015Flang\u0131\u00E7</label><input type=\"date\" class=\"form-control\" [(ngModel)]=\"filter.from\" /></div><div class=\"col-md-3\"><label>Biti\u015F</label><input type=\"date\" class=\"form-control\" [(ngModel)]=\"filter.until\" /></div>\r\n <div class=\"col-md-3\"><label>Form</label><select class=\"form-control\" [(ngModel)]=\"filter.formCode\"><option value=\"\">T\u00FCm\u00FC</option><option *ngFor=\"let form of visibleForms\" [value]=\"form.code\">{{ form.documentCode }} \u2013 {{ form.name }}</option></select></div>\r\n <div class=\"col-md-3\" *ngIf=\"filter.type === 'Process'\"><label>Tesis</label><select class=\"form-control\" [(ngModel)]=\"filter.facilityCode\"><option value=\"\">T\u00FCm\u00FC</option><option *ngFor=\"let facility of facilities\" [value]=\"facility.code\">{{ facility.name }}</option></select></div>\r\n <div class=\"col-md-3\" *ngIf=\"filter.type !== 'Process'\"><label>Hareket T\u00FCr\u00FC</label><select class=\"form-control\" [(ngModel)]=\"filter.movementTypeCode\"><option value=\"\">T\u00FCm\u00FC</option><option *ngFor=\"let type of types\" [value]=\"type.code\">{{ type.name }}</option></select></div>\r\n <div class=\"col-md-3 mt-3\" *ngIf=\"filter.type !== 'Process'\"><label>Muhatap</label><input class=\"form-control\" [(ngModel)]=\"filter.partner\" /></div><div class=\"col-md-3 mt-3\" *ngIf=\"filter.type !== 'Process'\"><label>Gemi</label><input class=\"form-control\" [(ngModel)]=\"filter.ship\" /></div>\r\n <div class=\"col-md-3 mt-3\" *ngIf=\"filter.type !== 'Process'\"><label>Gruplama</label><select class=\"form-control\" [(ngModel)]=\"filter.groupBy\"><option value=\"None\">Yok</option><option value=\"Ship\">Gemi / Parti</option><option value=\"Partner\">Muhatap</option><option value=\"Movement\">Hareket T\u00FCr\u00FC / Malzeme</option><option value=\"Month\">Ay</option></select></div>\r\n <div class=\"col-md-3 mt-3\"><label>Durum</label><select class=\"form-control\" [(ngModel)]=\"filter.status\"><option value=\"\">T\u00FCm\u00FC</option><ng-container *ngIf=\"filter.type === 'Process'\"><option value=\"Draft\">Taslak</option><option value=\"LaborantSigned\">Laborant \u0130mzal\u0131</option><option value=\"Checked\">Kontrol Edildi</option><option value=\"Approved\">Onayl\u0131</option></ng-container><ng-container *ngIf=\"filter.type !== 'Process'\"><option value=\"Draft\">Taslak</option><option value=\"Accepted\">Kabul</option><option value=\"Rejected\">Ret</option></ng-container></select></div>\r\n </div><div class=\"mt-3\"><button class=\"btn btn-primary mr-2\" (click)=\"load()\" [disabled]=\"busy\">Raporu Getir</button><button *ngIf=\"canExport\" class=\"btn btn-outline-primary mr-2\" (click)=\"pdf()\" [disabled]=\"busy\">PDF</button><button *ngIf=\"canExport\" class=\"btn btn-outline-primary\" (click)=\"excel()\" [disabled]=\"busy\">Excel</button></div>\r\n <div *ngIf=\"error\" class=\"alert alert-danger mt-3\">{{ error }}</div><div *ngIf=\"busy\" class=\"quality-loading\" role=\"status\">Rapor haz\u0131rlan\u0131yor\u2026</div>\r\n </div></div>\r\n <ng-container *ngIf=\"report as r\"><div class=\"card mt-3\"><div class=\"card-body\">Toplam Kay\u0131t: <strong>{{ r.totalRecords }}</strong> \u00B7 Ret: <strong>{{ r.rejectedRecords }}</strong> \u00B7 Ret Oran\u0131: <strong>% {{ r.rejectionRate }}</strong>\r\n <table *ngIf=\"r.type === 'Rejected'\" class=\"table table-sm mt-3\"><thead><tr><th>Grup</th><th>Toplam</th><th>Ret</th><th>Ret Oran\u0131 (%)</th></tr></thead><tbody><tr *ngFor=\"let g of r.rejectionSummary\"><td>{{ g.groupName }}</td><td>{{ g.total }}</td><td>{{ g.rejected }}</td><td>{{ g.rate }}</td></tr></tbody></table>\r\n </div></div>\r\n <div class=\"card mt-3\" *ngFor=\"let section of r.sections\"><div class=\"card-body\"><h5>{{ section.form.name }} \u2013 {{ section.groupName }}</h5><p class=\"text-muted\">{{ section.form.documentCode }} \u00B7 Yay\u0131n: {{ section.form.publicationDate | date:'dd.MM.yyyy' }} \u00B7 Revizyon: {{ section.form.revisionDate | date:'dd.MM.yyyy' }} / {{ section.form.revisionNumber }}</p>\r\n <div class=\"table-responsive\"><table class=\"table table-bordered table-sm\"><thead><tr><th>Tarih / Saat</th><th>{{ r.type === 'Process' ? 'Tank / Aktar\u0131lan Tank' : 'Plaka / Firma / Gemi' }}</th><th>Durum</th><th>Miktar ({{ section.form.quantityUnit || 'kg' }})</th><th *ngFor=\"let p of section.columns\">{{ p.name }} <small>{{ p.unit }}</small></th><th>Analizi Yapan / A\u00E7\u0131klama</th></tr></thead>\r\n <tbody><tr *ngFor=\"let row of section.rows\" [class.rejected-row]=\"row.status === 'Rejected'\"><td>{{ row.date | date:'dd.MM.yyyy HH:mm' }}</td><td>{{ row.composite ? 'Gemi Kompozit Numunesi' : r.type === 'Process' ? ((row.tank || row.outputTank) ? (row.tank || '') + ' / ' + (row.outputTank || '') : '') : row.plate }}<br />{{ row.partner }} {{ row.ship }}</td><td>{{ statusLabel(row.status) }}</td><td>{{ row.quantityKg == null ? '' : row.quantityKg / (section.form.quantityUnit === 't' ? 1000 : 1) }}</td><td *ngFor=\"let p of section.columns\" [class.out-of-limit]=\"measurement(row, p)?.outOfLimit\">{{ measurement(row, p)?.number != null ? (measurement(row, p)?.number | number:'1.0-8') : measurement(row, p)?.text }}</td><td>{{ row.analyst }}<br />{{ row.notes }}</td></tr>\r\n <tr class=\"bg-light\"><th>ORTALAMA</th><th>{{ section.averageMode === 'Weighted' ? 'Miktar a\u011F\u0131rl\u0131kl\u0131' : 'Aritmetik' }}</th><th>TOPLAM</th><th>{{ section.totalKg / (section.form.quantityUnit === 't' ? 1000 : 1) | number:'1.0-2' }}</th><td *ngFor=\"let p of section.columns\">{{ section.averages[p.code] | number:'1.0-8' }}</td><td></td></tr></tbody></table></div>\r\n </div></div><p *ngIf=\"!r.sections.length\" class=\"text-muted mt-3\">Se\u00E7ilen filtrelerde kay\u0131t bulunamad\u0131.</p>\r\n </ng-container>\r\n</div>\r\n", styles: [".quality-loading{padding:1.5rem;text-align:center;color:#5b526c}.print-only{display:none}.quality-status{display:inline-flex;align-items:center;gap:.5rem;padding:.55rem .85rem;border:1px solid transparent;border-radius:.4rem;font-size:.9375rem;font-weight:600;line-height:1.4}.quality-status-accepted{color:#166534;background:#dcfce7;border-color:#86efac}.quality-status-rejected{color:#991b1b;background:#fee2e2;border-color:#fca5a5}.quality-status-draft{color:#1e40af;background:#dbeafe;border-color:#93c5fd}.quality-status-waiting{color:#854d0e;background:#fef3c7;border-color:#fcd34d}.vehicle-table{min-width:1950px;white-space:nowrap}.actions{min-width:130px}.quality-questions-link{display:inline-flex;align-items:center;min-height:calc(1.5em + .5rem + 2px);margin-left:.4rem;padding:.25rem .5rem;color:#9a5a00;background:#fff3d6;border:1px solid #edb85b;border-radius:.2rem;font-size:.875rem;line-height:1.5;text-decoration:none}.quality-questions-link:hover,.quality-questions-link:focus{color:#fff;background:#b86b00;border-color:#b86b00;text-decoration:none}.intake-actions-cell{display:flex;align-items:center}:host ::ng-deep .intake-grid .dx-data-row>td{vertical-align:middle}.intake-actions-toggle{display:inline-flex;align-items:center;gap:.5rem;padding:.3rem .65rem;font-family:inherit;font-size:.8125rem;line-height:1.3}.intake-action-menu{min-width:210px;margin-top:.35rem;padding:.3rem;background:#fff;border:1px solid #dee2e6;border-radius:.375rem;box-shadow:0 .25rem .75rem #0000001a}.intake-action-menu .dropdown-item{display:block;text-align:left;border:0;border-radius:.25rem;background:none;color:#343a40;padding:.5rem .65rem;font-family:inherit;font-size:.8125rem;font-weight:400;line-height:1.4;text-decoration:none;white-space:nowrap;cursor:pointer}.intake-action-menu .dropdown-item:hover,.intake-action-menu .dropdown-item:focus-visible{background:#eef2ff;color:#2446b5}.page-size{width:85px}.vehicle-info{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1rem;margin:1rem 0}.vehicle-info label{font-size:.8rem;color:#6c757d;margin-bottom:.2rem}.vehicle-info p{background:#f5f3f8;padding:.55rem;min-height:2.5rem;overflow-wrap:anywhere}.measurement-table{min-width:700px}.measurement-table th{background:#f2edf7}.measurement-table td{vertical-align:middle}.out-of-limit,.rejected-row{background:#ffe6e9!important}.out-of-limit input,.out-of-limit select{border-color:#dc3545}@media (max-width: 900px){.vehicle-info{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width: 550px){.vehicle-info{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.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: i5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i3.DecimalPipe, name: "number" }, { kind: "pipe", type: i3.DatePipe, name: "date" }] });
|
|
1338
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: QualityReportsComponent, decorators: [{
|
|
1339
|
+
type: Component,
|
|
1340
|
+
args: [{ selector: 'lib-quality-reports', template: "<div class=\"container-fluid\"><h3>{{ filter.type === 'Process' ? 'Rafineri Proses Analiz Raporu' : filter.type === 'Rejected' ? 'Kalite Kontrol Ret Raporu' : 'Girdi Kontrol Raporlar\u0131' }}</h3>\r\n <div class=\"card\"><div class=\"card-body\"><div class=\"row\">\r\n <div class=\"col-md-3\"><label>Ba\u015Flang\u0131\u00E7</label><input type=\"date\" class=\"form-control\" [(ngModel)]=\"filter.from\" /></div><div class=\"col-md-3\"><label>Biti\u015F</label><input type=\"date\" class=\"form-control\" [(ngModel)]=\"filter.until\" /></div>\r\n <div class=\"col-md-3\"><label>Form</label><select class=\"form-control\" [(ngModel)]=\"filter.formCode\"><option value=\"\">T\u00FCm\u00FC</option><option *ngFor=\"let form of visibleForms\" [value]=\"form.code\">{{ form.documentCode }} \u2013 {{ form.name }}</option></select></div>\r\n <div class=\"col-md-3\" *ngIf=\"filter.type === 'Process'\"><label>Tesis</label><select class=\"form-control\" [(ngModel)]=\"filter.facilityCode\"><option value=\"\">T\u00FCm\u00FC</option><option *ngFor=\"let facility of facilities\" [value]=\"facility.code\">{{ facility.name }}</option></select></div>\r\n <div class=\"col-md-3\" *ngIf=\"filter.type !== 'Process'\"><label>Hareket T\u00FCr\u00FC</label><select class=\"form-control\" [(ngModel)]=\"filter.movementTypeCode\"><option value=\"\">T\u00FCm\u00FC</option><option *ngFor=\"let type of types\" [value]=\"type.code\">{{ type.name }}</option></select></div>\r\n <div class=\"col-md-3 mt-3\" *ngIf=\"filter.type !== 'Process'\"><label>Muhatap</label><input class=\"form-control\" [(ngModel)]=\"filter.partner\" /></div><div class=\"col-md-3 mt-3\" *ngIf=\"filter.type !== 'Process'\"><label>Gemi</label><input class=\"form-control\" [(ngModel)]=\"filter.ship\" /></div>\r\n <div class=\"col-md-3 mt-3\" *ngIf=\"filter.type !== 'Process'\"><label>Gruplama</label><select class=\"form-control\" [(ngModel)]=\"filter.groupBy\"><option value=\"None\">Yok</option><option value=\"Ship\">Gemi / Parti</option><option value=\"Partner\">Muhatap</option><option value=\"Movement\">Hareket T\u00FCr\u00FC / Malzeme</option><option value=\"Month\">Ay</option></select></div>\r\n <div class=\"col-md-3 mt-3\"><label>Durum</label><select class=\"form-control\" [(ngModel)]=\"filter.status\"><option value=\"\">T\u00FCm\u00FC</option><ng-container *ngIf=\"filter.type === 'Process'\"><option value=\"Draft\">Taslak</option><option value=\"LaborantSigned\">Laborant \u0130mzal\u0131</option><option value=\"Checked\">Kontrol Edildi</option><option value=\"Approved\">Onayl\u0131</option></ng-container><ng-container *ngIf=\"filter.type !== 'Process'\"><option value=\"Draft\">Taslak</option><option value=\"Accepted\">Kabul</option><option value=\"Rejected\">Ret</option></ng-container></select></div>\r\n </div><div class=\"mt-3\"><button class=\"btn btn-primary mr-2\" (click)=\"load()\" [disabled]=\"busy\">Raporu Getir</button><button *ngIf=\"canExport\" class=\"btn btn-outline-primary mr-2\" (click)=\"pdf()\" [disabled]=\"busy\">PDF</button><button *ngIf=\"canExport\" class=\"btn btn-outline-primary\" (click)=\"excel()\" [disabled]=\"busy\">Excel</button></div>\r\n <div *ngIf=\"error\" class=\"alert alert-danger mt-3\">{{ error }}</div><div *ngIf=\"busy\" class=\"quality-loading\" role=\"status\">Rapor haz\u0131rlan\u0131yor\u2026</div>\r\n </div></div>\r\n <ng-container *ngIf=\"report as r\"><div class=\"card mt-3\"><div class=\"card-body\">Toplam Kay\u0131t: <strong>{{ r.totalRecords }}</strong> \u00B7 Ret: <strong>{{ r.rejectedRecords }}</strong> \u00B7 Ret Oran\u0131: <strong>% {{ r.rejectionRate }}</strong>\r\n <table *ngIf=\"r.type === 'Rejected'\" class=\"table table-sm mt-3\"><thead><tr><th>Grup</th><th>Toplam</th><th>Ret</th><th>Ret Oran\u0131 (%)</th></tr></thead><tbody><tr *ngFor=\"let g of r.rejectionSummary\"><td>{{ g.groupName }}</td><td>{{ g.total }}</td><td>{{ g.rejected }}</td><td>{{ g.rate }}</td></tr></tbody></table>\r\n </div></div>\r\n <div class=\"card mt-3\" *ngFor=\"let section of r.sections\"><div class=\"card-body\"><h5>{{ section.form.name }} \u2013 {{ section.groupName }}</h5><p class=\"text-muted\">{{ section.form.documentCode }} \u00B7 Yay\u0131n: {{ section.form.publicationDate | date:'dd.MM.yyyy' }} \u00B7 Revizyon: {{ section.form.revisionDate | date:'dd.MM.yyyy' }} / {{ section.form.revisionNumber }}</p>\r\n <div class=\"table-responsive\"><table class=\"table table-bordered table-sm\"><thead><tr><th>Tarih / Saat</th><th>{{ r.type === 'Process' ? 'Tank / Aktar\u0131lan Tank' : 'Plaka / Firma / Gemi' }}</th><th>Durum</th><th>Miktar ({{ section.form.quantityUnit || 'kg' }})</th><th *ngFor=\"let p of section.columns\">{{ p.name }} <small>{{ p.unit }}</small></th><th>Analizi Yapan / A\u00E7\u0131klama</th></tr></thead>\r\n <tbody><tr *ngFor=\"let row of section.rows\" [class.rejected-row]=\"row.status === 'Rejected'\"><td>{{ row.date | date:'dd.MM.yyyy HH:mm' }}</td><td>{{ row.composite ? 'Gemi Kompozit Numunesi' : r.type === 'Process' ? ((row.tank || row.outputTank) ? (row.tank || '') + ' / ' + (row.outputTank || '') : '') : row.plate }}<br />{{ row.partner }} {{ row.ship }}</td><td>{{ statusLabel(row.status) }}</td><td>{{ row.quantityKg == null ? '' : row.quantityKg / (section.form.quantityUnit === 't' ? 1000 : 1) }}</td><td *ngFor=\"let p of section.columns\" [class.out-of-limit]=\"measurement(row, p)?.outOfLimit\">{{ measurement(row, p)?.number != null ? (measurement(row, p)?.number | number:'1.0-8') : measurement(row, p)?.text }}</td><td>{{ row.analyst }}<br />{{ row.notes }}</td></tr>\r\n <tr class=\"bg-light\"><th>ORTALAMA</th><th>{{ section.averageMode === 'Weighted' ? 'Miktar a\u011F\u0131rl\u0131kl\u0131' : 'Aritmetik' }}</th><th>TOPLAM</th><th>{{ section.totalKg / (section.form.quantityUnit === 't' ? 1000 : 1) | number:'1.0-2' }}</th><td *ngFor=\"let p of section.columns\">{{ section.averages[p.code] | number:'1.0-8' }}</td><td></td></tr></tbody></table></div>\r\n </div></div><p *ngIf=\"!r.sections.length\" class=\"text-muted mt-3\">Se\u00E7ilen filtrelerde kay\u0131t bulunamad\u0131.</p>\r\n </ng-container>\r\n</div>\r\n", styles: [".quality-loading{padding:1.5rem;text-align:center;color:#5b526c}.print-only{display:none}.quality-status{display:inline-flex;align-items:center;gap:.5rem;padding:.55rem .85rem;border:1px solid transparent;border-radius:.4rem;font-size:.9375rem;font-weight:600;line-height:1.4}.quality-status-accepted{color:#166534;background:#dcfce7;border-color:#86efac}.quality-status-rejected{color:#991b1b;background:#fee2e2;border-color:#fca5a5}.quality-status-draft{color:#1e40af;background:#dbeafe;border-color:#93c5fd}.quality-status-waiting{color:#854d0e;background:#fef3c7;border-color:#fcd34d}.vehicle-table{min-width:1950px;white-space:nowrap}.actions{min-width:130px}.quality-questions-link{display:inline-flex;align-items:center;min-height:calc(1.5em + .5rem + 2px);margin-left:.4rem;padding:.25rem .5rem;color:#9a5a00;background:#fff3d6;border:1px solid #edb85b;border-radius:.2rem;font-size:.875rem;line-height:1.5;text-decoration:none}.quality-questions-link:hover,.quality-questions-link:focus{color:#fff;background:#b86b00;border-color:#b86b00;text-decoration:none}.intake-actions-cell{display:flex;align-items:center}:host ::ng-deep .intake-grid .dx-data-row>td{vertical-align:middle}.intake-actions-toggle{display:inline-flex;align-items:center;gap:.5rem;padding:.3rem .65rem;font-family:inherit;font-size:.8125rem;line-height:1.3}.intake-action-menu{min-width:210px;margin-top:.35rem;padding:.3rem;background:#fff;border:1px solid #dee2e6;border-radius:.375rem;box-shadow:0 .25rem .75rem #0000001a}.intake-action-menu .dropdown-item{display:block;text-align:left;border:0;border-radius:.25rem;background:none;color:#343a40;padding:.5rem .65rem;font-family:inherit;font-size:.8125rem;font-weight:400;line-height:1.4;text-decoration:none;white-space:nowrap;cursor:pointer}.intake-action-menu .dropdown-item:hover,.intake-action-menu .dropdown-item:focus-visible{background:#eef2ff;color:#2446b5}.page-size{width:85px}.vehicle-info{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1rem;margin:1rem 0}.vehicle-info label{font-size:.8rem;color:#6c757d;margin-bottom:.2rem}.vehicle-info p{background:#f5f3f8;padding:.55rem;min-height:2.5rem;overflow-wrap:anywhere}.measurement-table{min-width:700px}.measurement-table th{background:#f2edf7}.measurement-table td{vertical-align:middle}.out-of-limit,.rejected-row{background:#ffe6e9!important}.out-of-limit input,.out-of-limit select{border-color:#dc3545}@media (max-width: 900px){.vehicle-info{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width: 550px){.vehicle-info{grid-template-columns:1fr}}\n"] }]
|
|
1341
|
+
}], ctorParameters: function () { return [{ type: QualityApiService }, { type: i2$1.ActivatedRoute }, { type: i2.PermissionService }]; } });
|
|
1342
|
+
|
|
1343
|
+
class QualityNotificationsComponent {
|
|
1344
|
+
constructor(api, router) {
|
|
1345
|
+
this.api = api;
|
|
1346
|
+
this.router = router;
|
|
1347
|
+
this.items = [];
|
|
1348
|
+
this.error = '';
|
|
1349
|
+
}
|
|
1350
|
+
ngOnInit() { this.api.notifications().subscribe({ next: x => this.items = x, error: e => this.error = errorMessage(e) }); }
|
|
1351
|
+
read(n) { this.api.readNotification(n.code).subscribe({ next: () => n.isRead = true, error: e => this.error = errorMessage(e) }); }
|
|
1352
|
+
open(n) { this.read(n); this.router.navigateByUrl(n.url); }
|
|
1353
|
+
}
|
|
1354
|
+
QualityNotificationsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: QualityNotificationsComponent, deps: [{ token: QualityApiService }, { token: i2$1.Router }], target: i0.ɵɵFactoryTarget.Component });
|
|
1355
|
+
QualityNotificationsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: QualityNotificationsComponent, selector: "lib-quality-notifications", ngImport: i0, template: `<div class="container-fluid"><h3>Kalite Bildirimleri</h3><div *ngIf="error" class="alert alert-danger">{{error}}</div><div class="card mb-2" *ngFor="let n of items"><div class="card-body"><strong>{{n.title}}</strong> <span *ngIf="!n.isRead" class="badge badge-primary">Yeni</span><small class="float-right">{{n.createdAt | date:'dd.MM.yyyy HH:mm'}}</small><div class="mt-2" [innerHTML]="n.body"></div><button class="btn btn-outline-primary mt-2" (click)="open(n)">Kaydı Aç</button><button class="btn btn-outline-secondary mt-2 ml-2" *ngIf="!n.isRead" (click)="read(n)">Okundu İşaretle</button></div></div><p *ngIf="!items.length">Bildirim bulunmuyor.</p></div>`, isInline: true, dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i3.DatePipe, name: "date" }] });
|
|
1356
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: QualityNotificationsComponent, decorators: [{
|
|
1357
|
+
type: Component,
|
|
1358
|
+
args: [{ selector: 'lib-quality-notifications', template: `<div class="container-fluid"><h3>Kalite Bildirimleri</h3><div *ngIf="error" class="alert alert-danger">{{error}}</div><div class="card mb-2" *ngFor="let n of items"><div class="card-body"><strong>{{n.title}}</strong> <span *ngIf="!n.isRead" class="badge badge-primary">Yeni</span><small class="float-right">{{n.createdAt | date:'dd.MM.yyyy HH:mm'}}</small><div class="mt-2" [innerHTML]="n.body"></div><button class="btn btn-outline-primary mt-2" (click)="open(n)">Kaydı Aç</button><button class="btn btn-outline-secondary mt-2 ml-2" *ngIf="!n.isRead" (click)="read(n)">Okundu İşaretle</button></div></div><p *ngIf="!items.length">Bildirim bulunmuyor.</p></div>` }]
|
|
1359
|
+
}], ctorParameters: function () { return [{ type: QualityApiService }, { type: i2$1.Router }]; } });
|
|
1360
|
+
class QualityNotificationBellComponent {
|
|
1361
|
+
constructor(api, config) {
|
|
1362
|
+
this.api = api;
|
|
1363
|
+
this.config = config;
|
|
1364
|
+
this.count = 0;
|
|
1365
|
+
}
|
|
1366
|
+
ngOnInit() { this.subscription = this.config.getOne$('currentUser').pipe(switchMap(user => (user === null || user === void 0 ? void 0 : user.isAuthenticated) ? timer(0, 60000).pipe(switchMap(() => this.api.unreadNotifications().pipe(catchError(() => of(0))))) : of(0))).subscribe(count => this.count = count); }
|
|
1367
|
+
ngOnDestroy() { var _a; (_a = this.subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe(); }
|
|
1368
|
+
}
|
|
1369
|
+
QualityNotificationBellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: QualityNotificationBellComponent, deps: [{ token: QualityApiService }, { token: i2.ConfigStateService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1370
|
+
QualityNotificationBellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: QualityNotificationBellComponent, selector: "lib-quality-notification-bell", ngImport: i0, template: `<a class="nav-link position-relative" routerLink="/kalite/notifications" aria-label="Kalite bildirimleri"><i class="fas fa-bell" aria-hidden="true"></i><span class="badge badge-danger" *ngIf="count">{{count}}</span></a>`, isInline: true, dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
|
|
1371
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: QualityNotificationBellComponent, decorators: [{
|
|
1372
|
+
type: Component,
|
|
1373
|
+
args: [{ selector: 'lib-quality-notification-bell', template: `<a class="nav-link position-relative" routerLink="/kalite/notifications" aria-label="Kalite bildirimleri"><i class="fas fa-bell" aria-hidden="true"></i><span class="badge badge-danger" *ngIf="count">{{count}}</span></a>` }]
|
|
1374
|
+
}], ctorParameters: function () { return [{ type: QualityApiService }, { type: i2.ConfigStateService }]; } });
|
|
1375
|
+
class QualityNotificationSettingsComponent {
|
|
1376
|
+
constructor(api) {
|
|
1377
|
+
this.api = api;
|
|
1378
|
+
this.settings = null;
|
|
1379
|
+
this.failures = [];
|
|
1380
|
+
this.qualityRoles = '';
|
|
1381
|
+
this.securityRoles = '';
|
|
1382
|
+
this.error = '';
|
|
1383
|
+
this.success = '';
|
|
1384
|
+
this.busy = false;
|
|
1385
|
+
}
|
|
1386
|
+
ngOnInit() { this.api.notificationFailures().subscribe({ next: x => this.failures = x }); this.api.notificationSettings().subscribe({ next: x => { this.settings = x; this.qualityRoles = x.qualityRoles.join('\n'); this.securityRoles = x.securityRoles.join('\n'); }, error: e => this.error = errorMessage(e) }); }
|
|
1387
|
+
save() {
|
|
1388
|
+
if (!this.settings)
|
|
1389
|
+
return;
|
|
1390
|
+
this.busy = true;
|
|
1391
|
+
this.settings.qualityRoles = this.qualityRoles.split('\n').map(x => x.trim()).filter(Boolean);
|
|
1392
|
+
this.settings.securityRoles = this.securityRoles.split('\n').map(x => x.trim()).filter(Boolean);
|
|
1393
|
+
this.api.saveNotificationSettings(this.settings).subscribe({ next: () => { this.busy = false; this.success = 'Bildirim ayarları kaydedildi.'; }, error: e => { this.error = errorMessage(e); this.busy = false; } });
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
QualityNotificationSettingsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: QualityNotificationSettingsComponent, deps: [{ token: QualityApiService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1397
|
+
QualityNotificationSettingsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: QualityNotificationSettingsComponent, selector: "lib-quality-notification-settings", ngImport: i0, template: `<div class="container-fluid"><h3>Kalite Bildirim Ayarları</h3><div *ngIf="error" class="alert alert-danger">{{error}}</div><div *ngIf="success" class="alert alert-success">{{success}}</div><div class="card" *ngIf="settings as s"><div class="card-body"><label class="d-block"><input type="checkbox" [(ngModel)]="s.portalEnabled" /> Portal içi bildirim</label><label class="d-block"><input type="checkbox" [(ngModel)]="s.emailEnabled" /> E-posta bildirimi</label><label class="d-block"><input type="checkbox" [(ngModel)]="s.reminderEnabled" /> Bekleyen kontrol hatırlatması</label><label class="mt-3">Portal Adresi (e-posta bağlantıları için)</label><input class="form-control" [(ngModel)]="s.portalBaseUrl" placeholder="https://portal.example.com" /><div class="row mt-3"><div class="col-md-4"><label>Hatırlatma Süresi (dakika)</label><input type="number" min="1" max="10080" class="form-control" [(ngModel)]="s.reminderMinutes" /></div><div class="col-md-4"><label>Kalite Alıcı Rolleri (her satır bir rol)</label><textarea class="form-control" rows="4" [(ngModel)]="qualityRoles"></textarea></div><div class="col-md-4"><label>Ret Bildirimi Alıcı Rolleri (her satır bir rol)</label><textarea class="form-control" rows="4" [(ngModel)]="securityRoles"></textarea></div></div><button class="btn btn-primary mt-3" (click)="save()" [disabled]="busy">Kaydet</button><h5 class="mt-4" *ngIf="failures.length">Gönderim Sorunları</h5><div class="alert alert-warning" *ngFor="let failure of failures">{{failure.title || failure.eventType}} · {{failure.error}}</div></div></div></div>`, isInline: true, dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.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: i5.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i5.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i5.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
1398
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: QualityNotificationSettingsComponent, decorators: [{
|
|
1399
|
+
type: Component,
|
|
1400
|
+
args: [{ selector: 'lib-quality-notification-settings', template: `<div class="container-fluid"><h3>Kalite Bildirim Ayarları</h3><div *ngIf="error" class="alert alert-danger">{{error}}</div><div *ngIf="success" class="alert alert-success">{{success}}</div><div class="card" *ngIf="settings as s"><div class="card-body"><label class="d-block"><input type="checkbox" [(ngModel)]="s.portalEnabled" /> Portal içi bildirim</label><label class="d-block"><input type="checkbox" [(ngModel)]="s.emailEnabled" /> E-posta bildirimi</label><label class="d-block"><input type="checkbox" [(ngModel)]="s.reminderEnabled" /> Bekleyen kontrol hatırlatması</label><label class="mt-3">Portal Adresi (e-posta bağlantıları için)</label><input class="form-control" [(ngModel)]="s.portalBaseUrl" placeholder="https://portal.example.com" /><div class="row mt-3"><div class="col-md-4"><label>Hatırlatma Süresi (dakika)</label><input type="number" min="1" max="10080" class="form-control" [(ngModel)]="s.reminderMinutes" /></div><div class="col-md-4"><label>Kalite Alıcı Rolleri (her satır bir rol)</label><textarea class="form-control" rows="4" [(ngModel)]="qualityRoles"></textarea></div><div class="col-md-4"><label>Ret Bildirimi Alıcı Rolleri (her satır bir rol)</label><textarea class="form-control" rows="4" [(ngModel)]="securityRoles"></textarea></div></div><button class="btn btn-primary mt-3" (click)="save()" [disabled]="busy">Kaydet</button><h5 class="mt-4" *ngIf="failures.length">Gönderim Sorunları</h5><div class="alert alert-warning" *ngFor="let failure of failures">{{failure.title || failure.eventType}} · {{failure.error}}</div></div></div></div>` }]
|
|
1401
|
+
}], ctorParameters: function () { return [{ type: QualityApiService }]; } });
|
|
1402
|
+
|
|
1403
|
+
const routes = [
|
|
1404
|
+
{
|
|
1405
|
+
path: '',
|
|
1406
|
+
pathMatch: 'full',
|
|
1407
|
+
redirectTo: 'process-analysis',
|
|
1408
|
+
},
|
|
1409
|
+
{ path: 'process-analysis', component: ProcessAnalysisComponent },
|
|
1410
|
+
{ path: 'parameters', component: QualityParametersComponent },
|
|
1411
|
+
{ path: 'intake', component: IntakeListComponent },
|
|
1412
|
+
{ path: 'intake/:id', component: IntakeFormComponent },
|
|
1413
|
+
{ path: 'definitions', component: QualityDefinitionsComponent },
|
|
1414
|
+
{ path: 'reports/input', component: QualityReportsComponent, data: { type: 'Input' } },
|
|
1415
|
+
{ path: 'reports/process', component: QualityReportsComponent, data: { type: 'Process' } },
|
|
1416
|
+
{ path: 'reports/rejected', component: QualityReportsComponent, data: { type: 'Rejected' } },
|
|
1417
|
+
{ path: 'notifications', component: QualityNotificationsComponent },
|
|
1418
|
+
{ path: 'notification-settings', component: QualityNotificationSettingsComponent },
|
|
1419
|
+
];
|
|
1420
|
+
class KaliteRoutingModule {
|
|
1421
|
+
}
|
|
1422
|
+
KaliteRoutingModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KaliteRoutingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1423
|
+
KaliteRoutingModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: KaliteRoutingModule, imports: [i2$1.RouterModule], exports: [RouterModule] });
|
|
1424
|
+
KaliteRoutingModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KaliteRoutingModule, imports: [RouterModule.forChild(routes), RouterModule] });
|
|
1425
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KaliteRoutingModule, decorators: [{
|
|
1426
|
+
type: NgModule,
|
|
1427
|
+
args: [{
|
|
1428
|
+
imports: [RouterModule.forChild(routes)],
|
|
1429
|
+
exports: [RouterModule],
|
|
1430
|
+
}]
|
|
1431
|
+
}] });
|
|
1432
|
+
|
|
1433
|
+
class KaliteNotificationModule {
|
|
1434
|
+
static forRoot() {
|
|
1435
|
+
return { ngModule: KaliteNotificationModule, providers: [{ provide: APP_INITIALIZER, multi: true, deps: [NavItemsService], useFactory: configureNotifications }] };
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
KaliteNotificationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KaliteNotificationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1439
|
+
KaliteNotificationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: KaliteNotificationModule, declarations: [QualityNotificationsComponent, QualityNotificationBellComponent, QualityNotificationSettingsComponent], imports: [CoreModule, FormsModule, RouterModule], exports: [QualityNotificationBellComponent, QualityNotificationsComponent, QualityNotificationSettingsComponent] });
|
|
1440
|
+
KaliteNotificationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KaliteNotificationModule, imports: [CoreModule, FormsModule, RouterModule] });
|
|
1441
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KaliteNotificationModule, decorators: [{
|
|
1442
|
+
type: NgModule,
|
|
1443
|
+
args: [{ declarations: [QualityNotificationsComponent, QualityNotificationBellComponent, QualityNotificationSettingsComponent], imports: [CoreModule, FormsModule, RouterModule], exports: [QualityNotificationBellComponent, QualityNotificationsComponent, QualityNotificationSettingsComponent] }]
|
|
1444
|
+
}] });
|
|
1445
|
+
function configureNotifications(nav) {
|
|
1446
|
+
return () => nav.addItems([{ id: 'Kalite.Notifications', component: QualityNotificationBellComponent, order: 90 }]);
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
class KaliteModule {
|
|
1450
|
+
static forChild() {
|
|
1451
|
+
return {
|
|
1452
|
+
ngModule: KaliteModule,
|
|
1453
|
+
providers: [],
|
|
1454
|
+
};
|
|
1455
|
+
}
|
|
1456
|
+
static forLazy() {
|
|
1457
|
+
return new LazyModuleFactory(KaliteModule.forChild());
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
KaliteModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KaliteModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1461
|
+
KaliteModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: KaliteModule, declarations: [KaliteComponent, ProcessAnalysisComponent, QualityParametersComponent, IntakeListComponent,
|
|
1462
|
+
IntakeFormComponent, QualityDefinitionsComponent, QualityReportsComponent], imports: [CoreModule, ThemeSharedModule, FormsModule, DxDataGridModule, NgbDropdownModule, KaliteNotificationModule, KaliteRoutingModule], exports: [ProcessAnalysisComponent, QualityParametersComponent] });
|
|
1463
|
+
KaliteModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KaliteModule, imports: [CoreModule, ThemeSharedModule, FormsModule, DxDataGridModule, NgbDropdownModule, KaliteNotificationModule, KaliteRoutingModule] });
|
|
1464
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: KaliteModule, decorators: [{
|
|
1465
|
+
type: NgModule,
|
|
1466
|
+
args: [{
|
|
1467
|
+
declarations: [KaliteComponent, ProcessAnalysisComponent, QualityParametersComponent, IntakeListComponent,
|
|
1468
|
+
IntakeFormComponent, QualityDefinitionsComponent, QualityReportsComponent],
|
|
1469
|
+
imports: [CoreModule, ThemeSharedModule, FormsModule, DxDataGridModule, NgbDropdownModule, KaliteNotificationModule, KaliteRoutingModule],
|
|
1470
|
+
exports: [ProcessAnalysisComponent, QualityParametersComponent],
|
|
1471
|
+
}]
|
|
1472
|
+
}] });
|
|
1473
|
+
|
|
1474
|
+
/*
|
|
1475
|
+
* Public API Surface of kalite
|
|
1476
|
+
*/
|
|
1477
|
+
|
|
1478
|
+
/**
|
|
1479
|
+
* Generated bundle index. Do not edit.
|
|
1480
|
+
*/
|
|
1481
|
+
|
|
1482
|
+
export { IntakeFormComponent, IntakeListComponent, KaliteComponent, KaliteModule, KaliteNotificationModule, KaliteService, ProcessAnalysisComponent, QualityApiService, QualityNotificationBellComponent, QualityNotificationSettingsComponent, QualityNotificationsComponent, QualityParametersComponent, configureNotifications };
|
|
1483
|
+
//# sourceMappingURL=hitsoft-kadooglu.kalite.mjs.map
|