feat(purchases): update terminology from "محصول" to "کالا" in purchase forms and templates
refactor(purchases): remove unused purchase receipt components and consolidate receipt template logic fix(suppliers): enhance suppliers select component to support full data option values style(tailwind): improve theme variables for better customization and consistency feat(shared): introduce abstract select component for reusable select field logic chore(purchases): clean up imports and improve component structure for better maintainability
This commit is contained in:
+195
@@ -0,0 +1,195 @@
|
||||
import { Maybe } from '@/core';
|
||||
import { ToastService } from '@/core/services/toast.service';
|
||||
import { InventoriesSelectComponent } from '@/modules/inventories/components/select/select.component';
|
||||
import { IInventoryResponse } from '@/modules/inventories/models';
|
||||
import { IProductResponse } from '@/modules/products/models';
|
||||
import { SuppliersSelectComponent } from '@/modules/suppliers/components/select/select.component';
|
||||
import { ISupplierResponse } from '@/modules/suppliers/models';
|
||||
import { InlineEditComponent, InputComponent } from '@/shared/components';
|
||||
import { IColumn } from '@/shared/components/pageDataList/page-data-list.component';
|
||||
import { PriceAlphabetDirective, PriceMaskDirective } from '@/shared/directives';
|
||||
import { UikitFlatpickrJalaliComponent } from '@/uikit';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, inject, Input, signal } from '@angular/core';
|
||||
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { ButtonDirective } from 'primeng/button';
|
||||
import { Card } from 'primeng/card';
|
||||
import { TableModule } from 'primeng/table';
|
||||
import { IPurchaseRequest } from '../../models';
|
||||
import { PurchasesService } from '../../services/main.service';
|
||||
import { PurchaseReceiptProductRowComponent } from './purchase-receipt-product-row.component';
|
||||
|
||||
@Component({
|
||||
selector: 'purchase-receipt-template',
|
||||
templateUrl: './purchase-receipt-template.component.html',
|
||||
standalone: true,
|
||||
|
||||
imports: [
|
||||
Card,
|
||||
InventoriesSelectComponent,
|
||||
SuppliersSelectComponent,
|
||||
InputComponent,
|
||||
TableModule,
|
||||
InlineEditComponent,
|
||||
PurchaseReceiptProductRowComponent,
|
||||
PriceAlphabetDirective,
|
||||
PriceMaskDirective,
|
||||
ButtonDirective,
|
||||
CommonModule,
|
||||
ReactiveFormsModule,
|
||||
UikitFlatpickrJalaliComponent,
|
||||
],
|
||||
})
|
||||
export class PurchaseReceiptTemplateComponent {
|
||||
private fb = inject(FormBuilder);
|
||||
|
||||
@Input() product?: IProductResponse;
|
||||
@Input() inventory?: IInventoryResponse;
|
||||
@Input() supplier?: ISupplierResponse;
|
||||
|
||||
columns = [
|
||||
{
|
||||
field: 'index',
|
||||
header: 'ردیف',
|
||||
width: '60px',
|
||||
},
|
||||
{
|
||||
field: 'sku',
|
||||
header: 'کد کالا',
|
||||
width: '120px',
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
header: 'نام کالا',
|
||||
minWidth: '160px',
|
||||
},
|
||||
{
|
||||
field: 'description',
|
||||
header: 'توضیحات',
|
||||
width: '200px',
|
||||
},
|
||||
{
|
||||
field: 'fee',
|
||||
header: 'قیمت واحد',
|
||||
width: '120px',
|
||||
},
|
||||
{
|
||||
field: 'count',
|
||||
header: 'تعداد',
|
||||
width: '80px',
|
||||
},
|
||||
{
|
||||
field: 'total',
|
||||
header: 'مبلغ کل',
|
||||
width: '140px',
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
header: '',
|
||||
width: '100px',
|
||||
},
|
||||
] as IColumn[];
|
||||
|
||||
form = this.fb.group({
|
||||
totalAmount: [300000, [Validators.required, Validators.min(0)]],
|
||||
code: ['122132', [Validators.required]],
|
||||
isSettled: [false],
|
||||
buyAt: ['2025-12-01', Validators.required],
|
||||
description: [''],
|
||||
products: this.fb.array([
|
||||
this.fb.group({
|
||||
product: [{ id: 1 } as Maybe<IProductResponse>, [Validators.required]],
|
||||
count: [2, [Validators.required, Validators.min(1)]],
|
||||
fee: [150000, [Validators.required, Validators.min(0)]],
|
||||
description: [''],
|
||||
total: [300000, [Validators.required, Validators.min(0)]],
|
||||
}),
|
||||
]),
|
||||
inventory: [{ id: 2 } as Maybe<IInventoryResponse>, [Validators.required]],
|
||||
supplier: [{ id: 1 } as Maybe<ISupplierResponse>, [Validators.required]],
|
||||
});
|
||||
|
||||
constructor(
|
||||
private service: PurchasesService,
|
||||
private toastService: ToastService,
|
||||
) {
|
||||
this.form.controls.products.valueChanges.subscribe((products) => {
|
||||
let totalAmount = 0;
|
||||
products.forEach((p: any) => {
|
||||
totalAmount += p.total || 0;
|
||||
});
|
||||
this.form.controls.totalAmount.setValue(totalAmount);
|
||||
});
|
||||
}
|
||||
|
||||
formIsSubmitted = signal(false);
|
||||
|
||||
ngOnInit() {
|
||||
this.formIsSubmitted.set(false);
|
||||
if (this.product) {
|
||||
this.form.controls.products.at(0).setValue({
|
||||
product: this.product,
|
||||
count: 0,
|
||||
fee: 0,
|
||||
description: '',
|
||||
total: 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get totalAmount() {
|
||||
return this.form.controls.totalAmount.value || 0;
|
||||
}
|
||||
|
||||
onAddProductClick() {
|
||||
this.form.controls.products.push(
|
||||
this.fb.group({
|
||||
product: [null as Maybe<IProductResponse>, [Validators.required]],
|
||||
count: [0, [Validators.required, Validators.min(1)]],
|
||||
fee: [0, [Validators.required, Validators.min(0)]],
|
||||
description: [''],
|
||||
total: [0, [Validators.required, Validators.min(0)]],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
removePurchaseItem(index: number) {
|
||||
this.form.controls.products.removeAt(index);
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.formIsSubmitted.set(true);
|
||||
this.form.markAllAsTouched();
|
||||
if (this.form.valid) {
|
||||
const { products, inventory, supplier, ...res } = this.form.value;
|
||||
|
||||
const payload = {
|
||||
...res,
|
||||
inventoryId: this.form.controls.inventory.value?.id,
|
||||
supplierId: this.form.controls.supplier.value?.id,
|
||||
items: this.form.controls.products.value.map((item) => {
|
||||
const { product, description, ...res } = item;
|
||||
return { ...res, productId: item.product?.id };
|
||||
}),
|
||||
} as IPurchaseRequest;
|
||||
console.log(payload);
|
||||
this.form.disable();
|
||||
|
||||
this.service.create(payload).subscribe({
|
||||
next: (res) => {
|
||||
this.toastService.success({ text: 'ثبت سند خرید با موفقیت انجام شد' });
|
||||
this.form.enable();
|
||||
this.form.reset();
|
||||
this.formIsSubmitted.set(false);
|
||||
},
|
||||
error: () => {
|
||||
this.form.enable();
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this.form.markAllAsTouched();
|
||||
}
|
||||
}
|
||||
|
||||
onCancel() {}
|
||||
}
|
||||
Reference in New Issue
Block a user