feat(inventories): implement inventory movement list and transfer functionality
- Added InventoryMovementListComponent to display stock movements with filtering options. - Created InventoriesTransferFormComponent for transferring stock between inventories. - Implemented product cardex view to show detailed inventory movements for specific products. - Enhanced product listing with loading states and improved UI components. - Introduced Jalali date formatting directive for better date representation. - Added utility functions for Jalali date conversions and comparisons. - Created reusable details info card component for displaying inventory details. - Updated movement reference types and tags for better categorization of inventory movements.
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
<p-table
|
||||
stripedRows
|
||||
[value]="items"
|
||||
[loading]="loading"
|
||||
showGridlines
|
||||
tableStyleClass="table-fixed border-collapse"
|
||||
scrollable
|
||||
>
|
||||
<ng-template #header>
|
||||
<tr>
|
||||
<th rowspan="2" [style]="{ textAlign: 'center', width: '4rem' }">ردیف</th>
|
||||
<th rowspan="2" [style]="{ textAlign: 'center', width: '8rem' }">تاریخ</th>
|
||||
<th rowspan="2" [style]="{ textAlign: 'center', width: '12rem' }">شرح</th>
|
||||
<th rowspan="2" [style]="{ textAlign: 'center', width: '6rem' }">شماره</th>
|
||||
<th rowspan="2" [style]="{ textAlign: 'center', minWidth: '14rem', width: '14rem' }">طرف حساب</th>
|
||||
<th rowspan="2" [style]="{ textAlign: 'center', width: '12rem' }">انبار</th>
|
||||
<th colspan="2" class="text-center!" [style]="{ width: '15rem' }">وارده</th>
|
||||
<th colspan="2" class="text-center!" [style]="{ width: '15rem' }">خروجی</th>
|
||||
<th colspan="3" class="text-center!" [style]="{ width: '25rem' }">مانده</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th [style]="{ textAlign: 'center', width: '5rem' }">تعداد</th>
|
||||
<th [style]="{ textAlign: 'center', width: '10rem' }">فی</th>
|
||||
<th [style]="{ textAlign: 'center', width: '5rem' }">تعداد</th>
|
||||
<th [style]="{ textAlign: 'center', width: '10rem' }">فی</th>
|
||||
<th [style]="{ textAlign: 'center', width: '5rem' }">تعداد</th>
|
||||
<th [style]="{ textAlign: 'center', width: '10rem' }">فی</th>
|
||||
<th [style]="{ textAlign: 'center', width: '10rem' }">مجموع قیمت</th>
|
||||
</tr>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #body let-item let-i="rowIndex">
|
||||
<tr>
|
||||
<td class="text-center!">{{ i + 1 }}</td>
|
||||
<td class="text-center!" [jalaliDate]="item.createdAt"></td>
|
||||
<td class="text-center!"><catalog-movement-reference-tag [type]="item.referenceType" /></td>
|
||||
<td class="text-center!">{{ item.referenceId || "-" }}</td>
|
||||
<td class="text-center!">{{ item.supplier?.name || "-" }}</td>
|
||||
<td class="text-center!">{{ item.inventory.name || "-" }}</td>
|
||||
<td class="text-center!">
|
||||
{{ item.type === "IN" ? item.quantity : 0 }}
|
||||
</td>
|
||||
<td class="text-center!">
|
||||
@if (item.type === "IN") {
|
||||
<span [appPriceMask]="item.fee"></span>
|
||||
} @else {
|
||||
0
|
||||
}
|
||||
</td>
|
||||
<td class="text-center!">
|
||||
{{ item.type === "OUT" ? item.quantity : 0 }}
|
||||
</td>
|
||||
<td class="text-center!">
|
||||
@if (item.type === "OUT") {
|
||||
<span [appPriceMask]="item.fee"></span>
|
||||
} @else {
|
||||
0
|
||||
}
|
||||
</td>
|
||||
<td class="text-center!">{{ item.remainedInStock }}</td>
|
||||
<td class="text-center!"><span [appPriceMask]="item.fee"></span></td>
|
||||
<td class="text-center!"><span [appPriceMask]="item.totalCost"></span></td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
</p-table>
|
||||
@@ -0,0 +1,22 @@
|
||||
import { CatalogMovementReferenceTagComponent } from '@/shared/catalog/movementReferenceTypes';
|
||||
import { JalaliDateDirective, PriceMaskDirective } from '@/shared/directives';
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { TableModule } from 'primeng/table';
|
||||
import { ICardexItem } from './type';
|
||||
|
||||
@Component({
|
||||
selector: 'shared-cardex',
|
||||
templateUrl: './cardex.component.html',
|
||||
imports: [
|
||||
TableModule,
|
||||
JalaliDateDirective,
|
||||
CatalogMovementReferenceTagComponent,
|
||||
PriceMaskDirective,
|
||||
],
|
||||
hostDirectives: [PriceMaskDirective],
|
||||
})
|
||||
export class CardexComponent {
|
||||
@Input() items: ICardexItem[] = [];
|
||||
@Input() loading: boolean = false;
|
||||
constructor() {}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { IInventoryStockMovementResponse } from '@/modules/inventories/models';
|
||||
|
||||
export interface ICardexItem extends IInventoryStockMovementResponse {}
|
||||
@@ -0,0 +1,11 @@
|
||||
<p-card class="w-full border border-primary-700">
|
||||
<div class="flex gap-5 text-primary-400">
|
||||
<div class="shrink-0 pt-1">
|
||||
<i [class]="'pi ' + icon + ' text-2xl'"></i>
|
||||
</div>
|
||||
<div class="grow flex flex-col gap-1">
|
||||
<span class="text-sm">{{ label }}</span>
|
||||
<span class="text-xl font-bold text-primary">{{ value }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</p-card>
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { Card } from 'primeng/card';
|
||||
|
||||
@Component({
|
||||
selector: 'details-info-card',
|
||||
templateUrl: './details-info-card.component.html',
|
||||
imports: [Card],
|
||||
})
|
||||
export class DetailsInfoCardComponent {
|
||||
@Input() icon: string = '';
|
||||
@Input() label: string = '';
|
||||
@Input() value: string = '';
|
||||
constructor() {}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { PaginatorComponent, UikitCopyComponent, UikitEmptyStateComponent } from '@/uikit';
|
||||
import { formatJalali } from '@/utils';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import {
|
||||
Component,
|
||||
@@ -124,8 +125,7 @@ export class PageDataListComponent<I> {
|
||||
switch (column.type) {
|
||||
case 'date':
|
||||
if (!data) return '-';
|
||||
const date = new Date(data);
|
||||
return isNaN(date.getTime()) ? '-' : date.toLocaleDateString();
|
||||
return formatJalali(data);
|
||||
case 'boolean':
|
||||
return data ? 'بله' : 'خیر';
|
||||
case 'price':
|
||||
|
||||
Reference in New Issue
Block a user