Ajout du support pour la position des ingrédients dans un mélange.

This commit is contained in:
FyloZ 2021-03-29 19:55:07 -04:00
parent 3f0be111e3
commit 3d14432b93
12 changed files with 206 additions and 118 deletions

View File

@ -28,17 +28,42 @@
</mat-card-content>
<mat-card-actions>
<button mat-raised-button color="primary" routerLink="/color/edit/{{recipeId}}">Retour</button>
<button *ngIf="editionMode && canDeleteMix" mat-raised-button color="warn" (click)="deleteConfirmBox.show()">Supprimer</button>
<button *ngIf="editionMode && canDeleteMix" mat-raised-button color="warn" (click)="deleteConfirmBox.show()">
Supprimer
</button>
<button mat-raised-button color="accent" [disabled]="!form.valid" (click)="submit()">Enregistrer</button>
</mat-card-actions>
</mat-card>
<ng-template #mixEditor>
<table #mixTable mat-table [dataSource]="mixMaterials">
<table #matTable mat-table [dataSource]="mixMaterials">
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef>Position</th>
<td mat-cell *matCellDef="let mixMaterial">
{{mixMaterial.position}}
</td>
</ng-container>
<ng-container matColumnDef="buttonsPosition">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let mixMaterial; let i = index">
{{i + 1}}
<ng-container *ngIf="(!hoveredMixMaterial && i === 0) || hoveredMixMaterial === mixMaterial">
<button
mat-mini-fab
color="primary"
class="mr-1"
[disabled]="mixMaterial.position <= 1"
(click)="decreasePosition(mixMaterial, matTable)">
<mat-icon svgIcon="arrow-up"></mat-icon>
</button>
<button
mat-mini-fab
color="primary"
[disabled]="mixMaterial.position >= mixMaterials.length"
(click)="increasePosition(mixMaterial, matTable)">
<mat-icon svgIcon="arrow-down"></mat-icon>
</button>
</ng-container>
</td>
</ng-container>
@ -67,10 +92,10 @@
<th mat-header-cell *matHeaderCellDef>Unités</th>
<td mat-cell *matCellDef="let mixMaterial" class="units-wrapper">
<ng-container *ngIf="materials">
<ng-container *ngIf="materialUsePercentages(mixMaterial)">
<ng-container *ngIf="mixMaterial.isPercents">
<p>%</p>
</ng-container>
<ng-container *ngIf="!materialUsePercentages(mixMaterial)">
<ng-container *ngIf="!mixMaterial.isPercents">
<ng-container *ngIf="!hoveredMixMaterial || hoveredMixMaterial != mixMaterial">
<span>{{units}}</span>
</ng-container>

View File

@ -1,3 +1,6 @@
mat-card
max-width: unset !important
td.units-wrapper p
width: 3rem
margin-bottom: 0

View File

@ -1,12 +1,17 @@
import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core'
import {Mix, MixMaterial, Recipe} from '../../../shared/model/recipe.model'
import {
Mix,
MixMaterial,
MixMaterialDto,
mixMaterialsAsMixMaterialsDto,
Recipe, RecipeStep,
sortMixMaterialsDto
} from '../../../shared/model/recipe.model'
import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component'
import {MixService} from '../../services/mix.service'
import {Observable} from 'rxjs'
import {RecipeService} from '../../services/recipe.service'
import {Material} from '../../../shared/model/material.model'
import {MaterialService} from '../../../material/service/material.service'
import {MaterialType} from '../../../shared/model/materialtype.model'
import {MaterialTypeService} from '../../../material-type/service/material-type.service'
import {FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms'
import {UNIT_MILLILITER} from '../../../shared/units'
@ -24,7 +29,7 @@ import {MatSelect} from '@angular/material/select'
styleUrls: ['./mix-editor.component.sass']
})
export class MixEditorComponent extends ErrorHandlingComponent {
@ViewChild('mixTable') mixTable: MatTable<MixMaterial>
@ViewChild('matTable') mixTable: MatTable<MixMaterial>
@ViewChild('deleteConfirmBox') deleteConfirmBox: ConfirmBoxComponent
@Input() mixId: number | null
@ -35,24 +40,24 @@ export class MixEditorComponent extends ErrorHandlingComponent {
mix: Mix | null
recipe: Recipe | null
materialTypes$: Observable<MaterialType[]>
materialTypes$ = this.materialTypeService.all
form: FormGroup
nameControl: FormControl
materialTypeControl: FormControl
mixMaterials = []
mixMaterials: MixMaterialDto[] = []
editionMode = false
units = UNIT_MILLILITER
hoveredMixMaterial: MixMaterial | null
columns = ['position', 'material', 'quantity', 'units', 'buttonRemove']
columns = ['position', 'buttonsPosition', 'material', 'quantity', 'units', 'buttonRemove']
deleting = false
handledErrorModels = [{
filter: error => error.status === 409 && !this.deleting,
messageProducer: error => `Un mélange avec le nom '${error.id}' existe déjà dans cette recette`
}, {
filter: error => error.error.status === 409 && this.deleting,
filter: error => error.error && error.error.status === 409 && this.deleting,
consumer: () => this.deleting = false,
messageProducer: () => 'Ce mélange est utilisé par un ou plusieurs autres mélanges'
}]
@ -85,28 +90,19 @@ export class MixEditorComponent extends ErrorHandlingComponent {
r => {
this.recipe = r
if (this.editionMode) {
this.subscribeEntityById(
this.mixService,
this.mixId,
m => {
this.mix = m
this.mixMaterials = this.mixService.extractMixMaterials(this.mix)
this.generateForm()
},
'/color/list'
)
this.mix = this.recipe.mixes.find(m => m.id === this.mixId)
this.mixMaterials = mixMaterialsAsMixMaterialsDto(this.mix)
} else {
this.mixMaterials.push({})
this.generateForm()
this.addBlankMixMaterial()
}
this.generateForm()
},
'/color/list'
)
this.materialTypes$ = this.materialTypeService.all
}
addRow() {
this.mixMaterials.push({materialId: null, quantity: null, percents: false})
this.addBlankMixMaterial()
this.mixTable.renderRows()
}
@ -115,6 +111,21 @@ export class MixEditorComponent extends ErrorHandlingComponent {
this.mixTable.renderRows()
}
increasePosition(mixMaterial: MixMaterialDto, table: MatTable<any>) {
this.updateMixMaterialPosition(mixMaterial, mixMaterial.position + 1)
this.sort(table)
}
decreasePosition(mixMaterial: MixMaterialDto, table: MatTable<any>) {
this.updateMixMaterialPosition(mixMaterial, mixMaterial.position - 1)
this.sort(table)
}
sort(table: MatTable<any>) {
this.mixMaterials = sortMixMaterialsDto(this.mixMaterials)
table.renderRows()
}
submit() {
this.save.emit({
name: this.nameControl.value,
@ -130,19 +141,6 @@ export class MixEditorComponent extends ErrorHandlingComponent {
this.subscribeAndNavigate(this.mixService.delete(this.mixId), `/color/edit/${this.recipeId}`)
}
materialUsePercentages(mixMaterial: any) {
if (!mixMaterial.materialId) {
return null
}
const material = this.getMaterialFromId(mixMaterial.materialId)
mixMaterial.percents = material && material.materialType.usePercentages
return mixMaterial.percents
}
getMaterialFromId(id: number): Material {
return id ? this.materials.filter(m => m.id === id)[0] : null
}
getAvailableMaterials(selector: MatSelect): Material[] {
return this.materials.filter(m => selector.value === m.id || this.mixMaterials.filter(mm => mm.materialId === m.id).length === 0)
}
@ -159,4 +157,24 @@ export class MixEditorComponent extends ErrorHandlingComponent {
materialType: this.materialTypeControl
})
}
private addBlankMixMaterial() {
this.mixMaterials.push(
new MixMaterialDto(null, 0, false, this.mixMaterials.length + 1)
)
}
private updateMixMaterialPosition(mixMaterial: MixMaterialDto, updatedPosition: number) {
if (!this.mixMaterialAtPosition(updatedPosition)) {
mixMaterial.position = updatedPosition
} else {
const conflictingStep = this.mixMaterialAtPosition(updatedPosition)
conflictingStep.position = mixMaterial.position
mixMaterial.position = updatedPosition
}
}
private mixMaterialAtPosition(position: number): MixMaterialDto {
return this.mixMaterials.find(m => m.position === position)
}
}

View File

@ -33,16 +33,22 @@
</mat-expansion-panel>
<ng-template #mixTable>
<table mat-table [dataSource]="mix.mixMaterials">
<table mat-table [dataSource]="mixMaterials">
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef>Position</th>
<td mat-cell *matCellDef="let mixMaterial">{{mixMaterial.position}}</td>
<td mat-footer-cell *matFooterCellDef></td>
</ng-container>
<ng-container matColumnDef="material">
<th mat-header-cell *matHeaderCellDef>Produit</th>
<td mat-cell *matCellDef="let mixMaterial">{{mixMaterial.material.name}}</td>
<td mat-cell *matCellDef="let mixMaterial">{{getMixMaterialFromDto(mixMaterial).material.name}}</td>
<td mat-footer-cell *matFooterCellDef></td>
</ng-container>
<ng-container matColumnDef="materialType">
<th mat-header-cell *matHeaderCellDef>Type</th>
<td mat-cell *matCellDef="let mixMaterial">{{mixMaterial.material.materialType.name}}</td>
<td mat-cell *matCellDef="let mixMaterial">{{getMixMaterialFromDto(mixMaterial).material.materialType.name}}</td>
<td mat-footer-cell *matFooterCellDef></td>
</ng-container>
@ -55,8 +61,8 @@
type="number"
min="0.001"
step="0.001"
[value]="getComputedQuantityRounded(mixMaterial)"
[disabled]="mixMaterial.material.materialType.usePercentages"
[value]="getMixMaterialQuantityRounded(mixMaterial)"
[disabled]="mixMaterial.isPercents"
(keyup)="changeQuantity($event, mixMaterial)"/>
</mat-form-field>
</td>
@ -76,12 +82,12 @@
<ng-container matColumnDef="quantityStatic">
<th mat-header-cell *matHeaderCellDef>Quantité</th>
<td mat-cell *matCellDef="let mixMaterial">{{getComputedQuantityRounded(mixMaterial)}}</td>
<td mat-cell *matCellDef="let mixMaterial">{{getMixMaterialQuantityRounded(mixMaterial)}}</td>
</ng-container>
<ng-container matColumnDef="quantityCalculated">
<th mat-header-cell *matHeaderCellDef>Calcul</th>
<td mat-cell *matCellDef="let mixMaterial; let i = index" [innerHTML]="getCalculatedQuantity(mixMaterial, i)"
<td mat-cell *matCellDef="let mixMaterial; let i = index" [innerHTML]="getCalculatedQuantityHtml(mixMaterial, i)"
class="mix-calculation"></td>
<td mat-footer-cell *matFooterCellDef></td>
</ng-container>
@ -89,8 +95,8 @@
<ng-container matColumnDef="quantityUnits">
<th mat-header-cell *matHeaderCellDef>Unités</th>
<td mat-cell *matCellDef="let mixMaterial">
<ng-container *ngIf="mixMaterial.material.materialType.usePercentages">%</ng-container>
<ng-container *ngIf="!mixMaterial.material.materialType.usePercentages">{{units}}</ng-container>
<ng-container *ngIf="mixMaterial.isPercents">%</ng-container>
<ng-container *ngIf="!mixMaterial.isPercents">{{units}}</ng-container>
</td>
<td mat-footer-cell *matFooterCellDef>{{units}}</td>
</ng-container>
@ -103,7 +109,7 @@
<button
mat-raised-button
color="accent"
[disabled]="!hasSimdutMap[mixMaterial.material.id]"
[disabled]="!hasSimdutMap[getMixMaterialFromDto(mixMaterial).material.id]"
(click)="openSimdutFile(mixMaterial)">
Fiche signalitique
</button>
@ -115,7 +121,7 @@
<tr mat-header-row *matHeaderRowDef="mixColumns"></tr>
<tr mat-row
*matRowDef="let mixMaterial; columns: mixColumns"
[class.low-quantity]="!editionMode && isInLowQuantity(mixMaterial.material.id)"
[class.low-quantity]="!editionMode && isInLowQuantity(mixMaterial.materialId)"
(mouseover)="hoveredMixMaterial = mixMaterial">
</tr>
<ng-container *ngIf="!editionMode">

View File

@ -1,5 +1,5 @@
import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core'
import {Mix, MixMaterial, Recipe} from '../../../shared/model/recipe.model'
import {Mix, MixMaterial, MixMaterialDto, mixMaterialsAsMixMaterialsDto, Recipe} from '../../../shared/model/recipe.model'
import {Subject} from 'rxjs'
import {SubscribingComponent} from '../../../shared/components/subscribing.component'
import {convertMixMaterialQuantity, UNIT_MILLILITER} from '../../../shared/units'
@ -18,7 +18,7 @@ import {MaterialService} from '../../../material/service/material.service'
})
export class MixTableComponent extends SubscribingComponent {
private readonly COLUMNS = ['material', 'materialType', 'quantity', 'quantityCalculated', 'quantityUnits', 'simdut']
private readonly COLUMNS_STATIC = ['material', 'materialType', 'quantityStatic', 'quantityUnits']
private readonly COLUMNS_EDIT = ['position', 'material', 'materialType', 'quantityStatic', 'quantityUnits']
@ViewChild('printingConfirmBox') printingConfirmBox: ConfirmBoxComponent
@ -28,13 +28,13 @@ export class MixTableComponent extends SubscribingComponent {
@Input() deductErrorBody
@Input() editionMode: boolean
@Output() locationChange = new EventEmitter<{ id: number, location: string }>()
@Output() quantityChange = new EventEmitter<{ id: number, materialId: number, quantity: number }>()
@Output() quantityChange = new EventEmitter<MixMaterialDto>()
@Output() deduct = new EventEmitter<void>()
@Output() printingErrorChange = new EventEmitter<number>()
mixColumns = this.COLUMNS
units = UNIT_MILLILITER
computedQuantities: { id: number, percents: boolean, quantity: number }[] = []
mixMaterials: MixMaterialDto[] = []
hoveredMixMaterial: MixMaterial | null
hasSimdutMap: any = {}
@ -55,23 +55,19 @@ export class MixTableComponent extends SubscribingComponent {
super.ngOnInit()
if (this.editionMode) {
this.mixColumns = this.COLUMNS_STATIC
this.mixColumns = this.COLUMNS_EDIT
}
this.mix.mixMaterials.forEach(m => this.computedQuantities.push({
id: m.id,
percents: m.material.materialType.usePercentages,
quantity: m.quantity
}))
this.mixMaterials = mixMaterialsAsMixMaterialsDto(this.mix)
this.subscribe(
this.units$,
u => this.convertQuantities(u)
)
this.mix.mixMaterials.map(mm => mm.material).forEach(material => this.subscribe(
this.materialService.hasSimdut(material.id),
b => this.hasSimdutMap[material.id] = b
this.mixMaterials.forEach(mixMaterial => this.subscribe(
this.materialService.hasSimdut(mixMaterial.materialId),
b => this.hasSimdutMap[mixMaterial.materialId] = b
)
)
}
@ -84,26 +80,30 @@ export class MixTableComponent extends SubscribingComponent {
const newQuantity = parseInt(event.target.value)
let ratio = 1
if (!isTotal) {
const originalQuantity = this.getComputedQuantity(mixMaterial.id)
const originalQuantity = this.findMixMaterialDto(mixMaterial.material.id)
ratio = newQuantity / originalQuantity.quantity
} else {
ratio = newQuantity / this.getTotalQuantity()
}
this.computedQuantities.forEach((q, i) => {
if (!q.percents) {
this.mixMaterials.forEach((q, i) => {
if (!q.isPercents) {
q.quantity *= ratio
}
this.emitQuantityChangeEvent(i)
})
}
getComputedQuantityRounded(mixMaterial: MixMaterial): number {
return this.round(this.getComputedQuantity(mixMaterial.id).quantity)
getMixMaterialFromDto(mixMaterialDto: MixMaterialDto): MixMaterial {
return this.mix.mixMaterials.find(m => m.material.id === mixMaterialDto.materialId)
}
getMixMaterialQuantityRounded(mixMaterial: MixMaterialDto): number {
return this.round(this.getMixMaterialFromDto(this.findMixMaterialDto(mixMaterial.materialId)).quantity)
}
getTotalQuantity(index: number = -1): number {
if (index === -1) {
index = this.computedQuantities.length - 1
index = this.mixMaterials.length - 1
}
let totalQuantity = 0
for (let i = 0; i <= index; i++) {
@ -112,7 +112,7 @@ export class MixTableComponent extends SubscribingComponent {
return totalQuantity
}
getCalculatedQuantity(mixMaterial: MixMaterial, index: number): string {
getCalculatedQuantityHtml(mixMaterial: MixMaterial, index: number): string {
const totalQuantity = this.round(this.getTotalQuantity(index))
const addedQuantity = this.round(this.calculateQuantity(index))
return `<span class="mix-calculated-quantity">+${addedQuantity}</span> <span class="mix-calculated-quantity">(${totalQuantity})</span>`
@ -127,8 +127,8 @@ export class MixTableComponent extends SubscribingComponent {
return Math.round(quantity * 1000) / 1000
}
openSimdutFile(mixMaterial: MixMaterial) {
window.open(`${environment.apiUrl}/material/${mixMaterial.material.id}/simdut`, '_blank')
openSimdutFile(mixMaterial: MixMaterialDto) {
window.open(`${environment.apiUrl}/material/${mixMaterial.materialId}/simdut`, '_blank')
}
async print() {
@ -169,28 +169,30 @@ export class MixTableComponent extends SubscribingComponent {
}
private emitQuantityChangeEvent(index: number) {
const quantity = this.mixMaterials[index]
this.quantityChange.emit({
id: this.mix.id,
materialId: this.computedQuantities[index].id,
quantity: this.calculateQuantity(index)
materialId: quantity.materialId,
quantity: this.calculateQuantity(index),
isPercents: quantity.isPercents,
position: quantity.position
})
}
private convertQuantities(newUnit: string) {
this.computedQuantities.forEach(q => q.quantity = convertMixMaterialQuantity(q, this.units, newUnit))
this.mixMaterials.forEach(q => q.quantity = convertMixMaterialQuantity(q, this.units, newUnit))
this.units = newUnit
}
private getComputedQuantity(id: number): any {
return this.computedQuantities.filter(q => q.id == id)[0]
private findMixMaterialDto(materialId: number): MixMaterialDto {
return this.mixMaterials.find(q => q.materialId == materialId)
}
private calculateQuantity(index: number): number {
const computedQuantity = this.computedQuantities[index]
if (!computedQuantity.percents) {
const computedQuantity = this.mixMaterials[index]
if (!computedQuantity.isPercents) {
return computedQuantity.quantity
}
return this.computedQuantities[0].quantity * (computedQuantity.quantity / 100)
return this.mixMaterials[0].quantity * (computedQuantity.quantity / 100)
}
}

View File

@ -11,7 +11,7 @@
[units$]="units$"
[deductErrorBody]="deductErrorBody"
[editionMode]="editionMode"
(quantityChange)="quantityChange.emit($event)"
(quantityChange)="quantityChange.emit({mixId: mix.id, mixMaterial: $event})"
(locationChange)="locationChange.emit($event)"
(deduct)="deduct.emit(mix.id)">
</cre-mix-table>

View File

@ -1,5 +1,5 @@
import {Component, EventEmitter, Input, Output} from '@angular/core';
import {Recipe} from "../../../shared/model/recipe.model";
import {MixMaterialDto, Recipe} from '../../../shared/model/recipe.model'
import {Subject} from "rxjs";
@Component({
@ -14,7 +14,7 @@ export class MixesCardComponent {
@Input() editionMode = false
@Output() locationChange = new EventEmitter<{ id: number, location: string }>()
@Output() quantityChange = new EventEmitter<{ id: number, materialId: number, quantity: number }>()
@Output() quantityChange = new EventEmitter<{ mixId: number, mixMaterial: MixMaterialDto}>()
@Output() deduct = new EventEmitter<number>()
@Output() printingErrorChange = new EventEmitter<number>()
}

View File

@ -2,7 +2,7 @@ import {Component} from '@angular/core'
import {RecipeService} from '../../services/recipe.service'
import {ActivatedRoute, Router} from '@angular/router'
import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component'
import {Recipe, recipeNoteForGroupId} from '../../../shared/model/recipe.model'
import {MixMaterialDto, Recipe, recipeNoteForGroupId} from '../../../shared/model/recipe.model'
import {Observable, Subject} from 'rxjs'
import {ErrorModel, ErrorService} from '../../../shared/service/error.service'
import {AlertService} from '../../../shared/service/alert.service'
@ -79,11 +79,11 @@ export class ExploreComponent extends ErrorHandlingComponent {
this.units$.next(unit)
}
changeQuantity(event: { id: number, materialId: number, quantity: number }) {
if (!this.quantitiesChanges.has(event.id)) {
this.quantitiesChanges.set(event.id, new Map<number, number>())
changeQuantity(event: { mixId: number, mixMaterial: MixMaterialDto}) {
if (!this.quantitiesChanges.has(event.mixId)) {
this.quantitiesChanges.set(event.mixId, new Map<number, number>())
}
this.quantitiesChanges.get(event.id).set(event.materialId, event.quantity)
this.quantitiesChanges.get(event.mixId).set(event.mixMaterial.materialId, event.mixMaterial.quantity)
}
changeMixLocation(event: { id: number, location: string }) {

View File

@ -5,6 +5,8 @@ import {Material} from '../../../../shared/model/material.model'
import {MaterialService} from '../../../../material/service/material.service'
import {MixService} from '../../../services/mix.service'
import {ErrorModel, ErrorService} from '../../../../shared/service/error.service'
import {MixMaterialDto} from '../../../../shared/model/recipe.model'
import {AlertService} from '../../../../shared/service/alert.service'
@Component({
selector: 'cre-mix-edit',
@ -21,6 +23,7 @@ export class MixEditComponent extends ErrorHandlingComponent {
constructor(
private materialService: MaterialService,
private mixService: MixService,
private alertService: AlertService,
errorService: ErrorService,
router: Router,
activatedRoute: ActivatedRoute
@ -41,9 +44,18 @@ export class MixEditComponent extends ErrorHandlingComponent {
}
submit(values) {
if(!this.mixMaterialsPositionAreValid(values.mixMaterials)) {
this.alertService.pushError('Les ingrédients ne peuvent pas avoir une position inférieure à 1')
return
}
this.subscribeAndNavigate(
this.mixService.updateWithUnits(this.mixId, values.name, values.materialTypeId, values.mixMaterials, values.units),
`/color/edit/${this.recipeId}`
)
}
private mixMaterialsPositionAreValid(mixMaterials: MixMaterialDto[]): boolean {
return !mixMaterials.find(m => m.position <= 0)
}
}

View File

@ -1,8 +1,8 @@
import {Injectable} from '@angular/core';
import {ApiService} from "../../shared/service/api.service";
import {convertMixMaterialQuantity, UNIT_MILLILITER} from "../../shared/units";
import {Observable} from "rxjs";
import {Mix} from "../../shared/model/recipe.model";
import {Injectable} from '@angular/core'
import {ApiService} from '../../shared/service/api.service'
import {convertMixMaterialQuantity, UNIT_MILLILITER} from '../../shared/units'
import {Observable} from 'rxjs'
import {Mix, MixMaterialDto} from '../../shared/model/recipe.model'
@Injectable({
providedIn: 'root'
@ -21,32 +21,33 @@ export class MixService {
return this.api.get<Mix>(`/recipe/mix/${id}`)
}
saveWithUnits(name: string, recipeId: number, materialTypeId: number, mixMaterials: { materialId: number, quantity: number, percents: boolean }[], units: string): Observable<void> {
saveWithUnits(name: string, recipeId: number, materialTypeId: number, mixMaterials: MixMaterialDto[], units: string): Observable<void> {
return this.save(name, recipeId, materialTypeId, this.convertMixMaterialsToMl(mixMaterials, units))
}
save(name: string, recipeId: number, materialTypeId: number, mixMaterials: { materialId: number, quantity: number }[]): Observable<void> {
save(name: string, recipeId: number, materialTypeId: number, mixMaterials: MixMaterialDto[]): Observable<void> {
const body = {
name,
recipeId,
materialTypeId,
mixMaterials: {}
mixMaterials: []
}
this.appendMixMaterialsToBody(mixMaterials, body)
return this.api.post('/recipe/mix', body)
}
updateWithUnits(id: number, name: string, materialTypeId: number, mixMaterials: { materialId: number, quantity: number, percents: boolean }[], units: string): Observable<void> {
updateWithUnits(id: number, name: string, materialTypeId: number, mixMaterials: MixMaterialDto[], units: string): Observable<void> {
return this.update(id, name, materialTypeId, this.convertMixMaterialsToMl(mixMaterials, units))
}
update(id: number, name: string, materialTypeId: number, mixMaterials: { materialId: number, quantity: number }[]): Observable<void> {
update(id: number, name: string, materialTypeId: number, mixMaterials: MixMaterialDto[]): Observable<void> {
const body = {
id,
name,
materialTypeId,
mixMaterials: {}
mixMaterials: []
}
this.appendMixMaterialsToBody(mixMaterials, body)
return this.api.put('/recipe/mix', body)
}
@ -55,25 +56,21 @@ export class MixService {
return this.api.delete(`/recipe/mix/${id}`)
}
extractMixMaterials(mix: Mix): { materialId: number, quantity: number, percents: boolean }[] {
return mix.mixMaterials.map(m => {
return {materialId: m.material.id, quantity: m.quantity, percents: m.material.materialType.usePercentages}
})
}
private convertMixMaterialsToMl(mixMaterials: { materialId: number, quantity: number, percents: boolean }[], units: string): { materialId: number, quantity: number }[] {
private convertMixMaterialsToMl(mixMaterials: MixMaterialDto[], units: string): MixMaterialDto[] {
return mixMaterials.map(m => {
return {
materialId: m.materialId,
quantity: convertMixMaterialQuantity(m, units, UNIT_MILLILITER)
}
m.quantity = convertMixMaterialQuantity(m, units, UNIT_MILLILITER)
return m
})
}
private appendMixMaterialsToBody(mixMaterials: { materialId: number, quantity: number }[], body: any) {
mixMaterials
.filter(m => m.materialId != null && m.quantity != null)
.forEach(m => body.mixMaterials[m.materialId] = m.quantity)
private appendMixMaterialsToBody(mixMaterials: MixMaterialDto[], body: any) {
mixMaterials.filter(m => m.materialId != null && m.quantity != null).forEach(m => {
body.mixMaterials.push({
materialId: m.materialId,
quantity: m.quantity,
position: m.position
})
})
}
}

View File

@ -58,6 +58,16 @@ export class MixMaterial {
}
}
export class MixMaterialDto {
constructor(
public materialId: number,
public quantity: number,
public isPercents: boolean,
public position: number
) {
}
}
class MixType {
constructor(
public id: number,
@ -90,3 +100,16 @@ export function sortRecipeSteps(steps: RecipeStep[]): RecipeStep[] {
return steps.sort((a, b) => a.position - b.position)
}
export function mixMaterialsAsMixMaterialsDto(mix: Mix): MixMaterialDto[] {
return sortMixMaterialsDto(mix.mixMaterials.map(m => new MixMaterialDto(
m.material.id,
m.quantity,
m.material.materialType.usePercentages,
m.position
)))
}
export function sortMixMaterialsDto(mixMaterials: MixMaterialDto[]): MixMaterialDto[] {
return mixMaterials.sort((a, b) => a.position - b.position)
}

View File

@ -1,3 +1,5 @@
import {MixMaterialDto} from './model/recipe.model'
export const UNIT_MILLILITER = 'mL'
export const UNIT_LITER = 'L'
export const UNIT_GALLON = 'gal'
@ -23,8 +25,8 @@ export const UNIT_RATIOS = {
}
}
export function convertMixMaterialQuantity(computedQuantity: { percents: boolean, quantity: number }, from: string, to: string): number {
return !computedQuantity.percents ? convertQuantity(computedQuantity.quantity, from, to) : computedQuantity.quantity
export function convertMixMaterialQuantity(computedQuantity: MixMaterialDto, from: string, to: string): number {
return !computedQuantity.isPercents ? convertQuantity(computedQuantity.quantity, from, to) : computedQuantity.quantity
}
export function convertQuantity(quantity: number, from: string, to: string): number {