update saleinvoice single and create return from sale form, update agent.md file,
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
<form [formGroup]="form" (ngSubmit)="submit()">
|
||||
<p-message severity="info" icon="pi pi-info-circle">
|
||||
در برگشت از فروش صورتحساب شما میتوانید صرفا تعداد محصولات و خدمات خود را کم و حذف کنید و حداقل مقدار محصولات و خدمات
|
||||
شما ۱ می باشد.
|
||||
</p-message>
|
||||
|
||||
<field-invoice-date [control]="form.controls.invoice_date" />
|
||||
@for (item of items.controls; track (goodItems()[$index]?.good_snapshot!.id || '') + ($index + '')) {
|
||||
<div class="py-2">
|
||||
<shared-return-form-item
|
||||
[control]="item.controls.quantity"
|
||||
[good]="goodItems()[$index]!.good_snapshot"
|
||||
[index]="$index" />
|
||||
</div>
|
||||
}
|
||||
|
||||
<app-form-footer-actions />
|
||||
</form>
|
||||
@@ -0,0 +1,108 @@
|
||||
import { Maybe } from '@/core';
|
||||
import { AbstractForm } from '@/shared/abstractClasses';
|
||||
import { formatDate, GREGORIAN_DATE_FORMATS } from '@/utils';
|
||||
import { Component, computed, Input, signal, SimpleChanges } from '@angular/core';
|
||||
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { Message } from 'primeng/message';
|
||||
import { FieldInvoiceDateComponent } from '../../fields/invoice_date.component';
|
||||
import { FormFooterActionsComponent } from '../../formFooterActions/form-footer-actions.component';
|
||||
import { IInvoiceItem } from '../sale-invoice-full-response.model';
|
||||
import { SharedReturnFormItemComponent } from './item-form.component';
|
||||
|
||||
type ItemForm = FormGroup<{
|
||||
quantity: FormControl<number | null>;
|
||||
}>;
|
||||
|
||||
type BackFromSaleFormValue = {
|
||||
items: {
|
||||
id: string;
|
||||
quantity: number;
|
||||
maxQuantity: number;
|
||||
}[];
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: 'shared-return-form',
|
||||
templateUrl: 'form.component.html',
|
||||
imports: [
|
||||
Message,
|
||||
FormFooterActionsComponent,
|
||||
ReactiveFormsModule,
|
||||
FieldInvoiceDateComponent,
|
||||
SharedReturnFormItemComponent,
|
||||
],
|
||||
})
|
||||
export class SharedReturnFormComponent extends AbstractForm<
|
||||
BackFromSaleFormValue,
|
||||
any,
|
||||
IInvoiceItem[]
|
||||
> {
|
||||
@Input({ required: true }) invoiceDate!: string;
|
||||
|
||||
form = this.fb.group({
|
||||
invoice_date: [this.invoiceDate],
|
||||
items: this.fb.array<ItemForm>([], {
|
||||
// validators: [atLeastOneQuantityValidator],
|
||||
}),
|
||||
});
|
||||
|
||||
goodItems = computed(() => this.initialValues!);
|
||||
|
||||
get items() {
|
||||
return this.form.controls.items;
|
||||
}
|
||||
|
||||
preparedCalculation = signal<Maybe<any>>(null);
|
||||
|
||||
init() {
|
||||
this.initForm();
|
||||
this.prepareCalculation();
|
||||
}
|
||||
|
||||
prepareCalculation() {
|
||||
const calculated = [];
|
||||
this.initialValues?.forEach((item) => {});
|
||||
}
|
||||
|
||||
initForm() {
|
||||
this.items.clear();
|
||||
this.form.controls.invoice_date.setValue(
|
||||
formatDate(this.invoiceDate, 'gregory', 'en', GREGORIAN_DATE_FORMATS.FULL)
|
||||
);
|
||||
|
||||
this.initialValues?.forEach((item: any) => {
|
||||
this.items.push(
|
||||
this.fb.group({
|
||||
quantity: [
|
||||
Number(item.quantity),
|
||||
[Validators.required, Validators.min(0), Validators.max(Number(item.quantity))],
|
||||
],
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
override ngOnInit(): void {
|
||||
this.init();
|
||||
}
|
||||
|
||||
override ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes['initialValues']) {
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
|
||||
override submitForm() {
|
||||
const payload = this.items.controls.map((control) => ({
|
||||
id: control.get('id')?.value,
|
||||
quantity: control.get('quantity')?.value,
|
||||
}));
|
||||
|
||||
if (!payload.some((item) => item.quantity)) {
|
||||
this.toastService.warn({
|
||||
text: 'حداقل مقدار یکی از کالاها/خدمات باید بیشتر از ۰ باشد.',
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<div>
|
||||
<p-divider align="right">
|
||||
{{ index + 1 }}- <b>{{ good.name }}</b>
|
||||
</p-divider>
|
||||
<app-input
|
||||
[control]="control"
|
||||
name="quantity"
|
||||
[label]="good.measure_unit.name"
|
||||
type="number"
|
||||
[suffix]="good.measure_unit.name"
|
||||
[max]="control.defaultValue || undefined"
|
||||
[min]="0" />
|
||||
</div>
|
||||
@@ -0,0 +1,45 @@
|
||||
import { Maybe } from '@/core';
|
||||
import { Component, Input, signal, SimpleChanges } from '@angular/core';
|
||||
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
|
||||
import { Divider } from 'primeng/divider';
|
||||
import { InputComponent } from '../../input/input.component';
|
||||
import { Goodsnapshot } from '../sale-invoice-full-response.model';
|
||||
|
||||
type ItemForm = FormGroup<{
|
||||
quantity: FormControl<number | null>;
|
||||
}>;
|
||||
|
||||
type BackFromSaleFormValue = {
|
||||
items: {
|
||||
id: string;
|
||||
quantity: number;
|
||||
maxQuantity: number;
|
||||
}[];
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: 'shared-return-form-item',
|
||||
templateUrl: './item-form.component.html',
|
||||
imports: [InputComponent, ReactiveFormsModule, Divider],
|
||||
})
|
||||
export class SharedReturnFormItemComponent {
|
||||
@Input({ required: true }) control!: FormControl<number | null>;
|
||||
@Input({ required: true }) good!: Goodsnapshot;
|
||||
@Input({ required: true }) index!: number;
|
||||
|
||||
preparedCalculation = signal<Maybe<any>>(null);
|
||||
|
||||
prepareCalculation() {
|
||||
const calculated = [];
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.prepareCalculation();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes['initialValues']) {
|
||||
this.prepareCalculation();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ export interface ISaleInvoiceFullRawResponse {
|
||||
consumer_account: ConsumerAccount;
|
||||
pos: Pos;
|
||||
payments: Payment[];
|
||||
items: Item[];
|
||||
items: IInvoiceItem[];
|
||||
invoice_number: number;
|
||||
type: IEnumTranslate<InvoiceTypes>;
|
||||
created_at: string;
|
||||
@@ -30,7 +30,7 @@ export interface ISaleInvoiceFullRawResponse {
|
||||
|
||||
export interface ISaleInvoiceFullResponse extends ISaleInvoiceFullRawResponse {}
|
||||
|
||||
interface Item {
|
||||
export interface IInvoiceItem {
|
||||
id: string;
|
||||
good_id: string;
|
||||
service_id: null;
|
||||
@@ -64,9 +64,7 @@ interface Category {
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
interface Goodsnapshot {
|
||||
good: Good;
|
||||
}
|
||||
export interface Goodsnapshot extends Good {}
|
||||
|
||||
interface Good {
|
||||
id: string;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="listKeyValue">
|
||||
<app-key-value label="شماره صورتحساب" [value]="invoice.invoice_number" />
|
||||
<app-key-value label="شماره منحصر به فرد مالیاتی" [value]="invoice.tax_id" />
|
||||
<app-key-value label="تاریخ صورتحساب" [value]="invoice.invoice_date" type="date" />
|
||||
<app-key-value label="تاریخ ایجاد صورتحساب" [value]="invoice.created_at" type="dateTime" />
|
||||
<app-key-value label="نوع صورتحساب">
|
||||
@@ -109,4 +110,8 @@
|
||||
</app-page-data-list>
|
||||
</app-card-data>
|
||||
</div>
|
||||
|
||||
<shared-light-bottomsheet [(visible)]="showBackFromSaleForm" header=" برگشت از فروش">
|
||||
<shared-return-form [initialValues]="invoice.items" [invoiceDate]="invoice.invoice_date" />
|
||||
</shared-light-bottomsheet>
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import { ProgressSpinner } from 'primeng/progressspinner';
|
||||
import { TableModule } from 'primeng/table';
|
||||
import { Observable } from 'rxjs';
|
||||
import { AppConfirmationService } from '../confirmationDialog/confirmation-dialog.service';
|
||||
import { SharedReturnFormComponent } from './returnForm/form.component';
|
||||
|
||||
export type TSaleInvoiceSingleViewVariant = 'full' | 'customer' | 'pos';
|
||||
|
||||
@@ -65,6 +66,7 @@ export type TSaleInvoiceSingleViewVariant = 'full' | 'customer' | 'pos';
|
||||
CatalogInvoiceSettlementTypeTagComponent,
|
||||
SharedLightBottomsheetComponent,
|
||||
ProgressSpinner,
|
||||
SharedReturnFormComponent,
|
||||
],
|
||||
})
|
||||
export class SharedSaleInvoiceSingleViewComponent {
|
||||
@@ -90,6 +92,8 @@ export class SharedSaleInvoiceSingleViewComponent {
|
||||
@ViewChild('totalAmount', { static: false }) totalAmount!: TemplateRef<any>;
|
||||
|
||||
moreActionMenuItems = signal<MenuItem[]>([]);
|
||||
showCorrectionForm = signal(false);
|
||||
showBackFromSaleForm = signal(false);
|
||||
|
||||
constructor() {
|
||||
this.showErrors = this.showErrors.bind(this);
|
||||
@@ -112,16 +116,17 @@ export class SharedSaleInvoiceSingleViewComponent {
|
||||
send() {
|
||||
this.onSendToTsp.emit();
|
||||
}
|
||||
showRevokeConfirmation() {
|
||||
this.confirmationService.ask({
|
||||
async showRevokeConfirmation() {
|
||||
await this.confirmationService.ask({
|
||||
header: `ابطال صورتحساب شماره ${this.invoice!.invoice_number}`,
|
||||
message: `در صورت تایید ابطال صورتحساب شماره ${this.invoice!.invoice_number} بر روی دکمهی ابطال کلیک کنید.`,
|
||||
acceptLabel: 'ابطال',
|
||||
acceptButtonProps: {
|
||||
severity: 'dangerdock',
|
||||
},
|
||||
variant: 'danger',
|
||||
|
||||
accept: () => {
|
||||
accept: async () => {
|
||||
// this.deferredInstallPrompt.prompt();
|
||||
// this.deferredInstallPrompt.userChoice.finally(() => {
|
||||
// this.deferredInstallPrompt = null;
|
||||
@@ -133,7 +138,9 @@ export class SharedSaleInvoiceSingleViewComponent {
|
||||
});
|
||||
}
|
||||
showCorrection() {}
|
||||
showBackFromSale() {}
|
||||
showBackFromSale() {
|
||||
this.showBackFromSaleForm.set(true);
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes['invoice'] && this.invoice) {
|
||||
@@ -320,21 +327,18 @@ export class SharedSaleInvoiceSingleViewComponent {
|
||||
{
|
||||
label: 'اجرت',
|
||||
value: formatWithCurrency(item.payload.wages),
|
||||
show:
|
||||
mustPrintConfig.items?.wage && item.good_snapshot.good.pricing_model === 'GOLD',
|
||||
show: mustPrintConfig.items?.wage && item.good_snapshot.pricing_model === 'GOLD',
|
||||
},
|
||||
{
|
||||
label: 'سود',
|
||||
value: formatWithCurrency(item.payload.wages),
|
||||
show:
|
||||
mustPrintConfig.items?.profit && item.good_snapshot.good.pricing_model === 'GOLD',
|
||||
show: mustPrintConfig.items?.profit && item.good_snapshot.pricing_model === 'GOLD',
|
||||
},
|
||||
{
|
||||
label: 'حقالعمل',
|
||||
value: formatWithCurrency(item.payload.commission),
|
||||
show:
|
||||
mustPrintConfig.items?.commission &&
|
||||
item.good_snapshot.good.pricing_model === 'GOLD',
|
||||
mustPrintConfig.items?.commission && item.good_snapshot.pricing_model === 'GOLD',
|
||||
},
|
||||
{
|
||||
label: 'مالیات بر ارزش افزوده',
|
||||
|
||||
Reference in New Issue
Block a user