diff --git a/hesabixCore/migrations/Version20250820090839.php b/hesabixCore/migrations/Version20250820090839.php new file mode 100644 index 0000000..53ebfb7 --- /dev/null +++ b/hesabixCore/migrations/Version20250820090839.php @@ -0,0 +1,47 @@ +addSql(<<<'SQL' + ALTER TABLE business DROP invoice_approver, DROP warehouse_approver, DROP financial_approver + SQL); + $this->addSql(<<<'SQL' + ALTER TABLE hesabdari_doc CHANGE is_preview is_preview TINYINT(1) DEFAULT 0, CHANGE is_approved is_approved TINYINT(1) DEFAULT 1 + SQL); + $this->addSql(<<<'SQL' + ALTER TABLE import_workflow DROP total_amount, DROP total_amount_irr + SQL); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql(<<<'SQL' + ALTER TABLE business ADD invoice_approver VARCHAR(255) DEFAULT NULL, ADD warehouse_approver VARCHAR(255) DEFAULT NULL, ADD financial_approver VARCHAR(255) DEFAULT NULL + SQL); + $this->addSql(<<<'SQL' + ALTER TABLE hesabdari_doc CHANGE is_preview is_preview TINYINT(1) DEFAULT NULL, CHANGE is_approved is_approved TINYINT(1) DEFAULT NULL + SQL); + $this->addSql(<<<'SQL' + ALTER TABLE import_workflow ADD total_amount VARCHAR(255) DEFAULT NULL, ADD total_amount_irr VARCHAR(255) DEFAULT NULL + SQL); + } +} diff --git a/hesabixCore/migrations/Version20250820104158.php b/hesabixCore/migrations/Version20250820104158.php new file mode 100644 index 0000000..abb2a78 --- /dev/null +++ b/hesabixCore/migrations/Version20250820104158.php @@ -0,0 +1,47 @@ +addSql(<<<'SQL' + ALTER TABLE business DROP invoice_approver, DROP warehouse_approver, DROP financial_approver + SQL); + $this->addSql(<<<'SQL' + ALTER TABLE hesabdari_doc CHANGE is_preview is_preview TINYINT(1) DEFAULT 0, CHANGE is_approved is_approved TINYINT(1) DEFAULT 1 + SQL); + $this->addSql(<<<'SQL' + ALTER TABLE import_workflow DROP total_amount, DROP total_amount_irr + SQL); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql(<<<'SQL' + ALTER TABLE business ADD invoice_approver VARCHAR(255) DEFAULT NULL, ADD warehouse_approver VARCHAR(255) DEFAULT NULL, ADD financial_approver VARCHAR(255) DEFAULT NULL + SQL); + $this->addSql(<<<'SQL' + ALTER TABLE hesabdari_doc CHANGE is_preview is_preview TINYINT(1) DEFAULT NULL, CHANGE is_approved is_approved TINYINT(1) DEFAULT NULL + SQL); + $this->addSql(<<<'SQL' + ALTER TABLE import_workflow ADD total_amount VARCHAR(255) DEFAULT NULL, ADD total_amount_irr VARCHAR(255) DEFAULT NULL + SQL); + } +} diff --git a/hesabixCore/migrations/Version20250820174027.php b/hesabixCore/migrations/Version20250820174027.php new file mode 100644 index 0000000..964b689 --- /dev/null +++ b/hesabixCore/migrations/Version20250820174027.php @@ -0,0 +1,63 @@ +addSql('ALTER TABLE import_workflow MODIFY exchange_rate DECIMAL(15,2) DEFAULT NULL'); + + // ImportWorkflowItem table - monetary fields + $this->addSql('ALTER TABLE import_workflow_item MODIFY unit_price DECIMAL(15,2) DEFAULT NULL'); + $this->addSql('ALTER TABLE import_workflow_item MODIFY unit_price_irr DECIMAL(15,2) DEFAULT NULL'); + $this->addSql('ALTER TABLE import_workflow_item MODIFY total_price DECIMAL(15,2) DEFAULT NULL'); + $this->addSql('ALTER TABLE import_workflow_item MODIFY total_price_irr DECIMAL(15,2) DEFAULT NULL'); + + // ImportWorkflowPayment table - monetary fields + $this->addSql('ALTER TABLE import_workflow_payment MODIFY amount DECIMAL(15,2) DEFAULT NULL'); + $this->addSql('ALTER TABLE import_workflow_payment MODIFY amount_irr DECIMAL(15,2) DEFAULT NULL'); + + // ImportWorkflowCustoms table - monetary fields + $this->addSql('ALTER TABLE import_workflow_customs MODIFY customs_duty DECIMAL(15,2) DEFAULT NULL'); + $this->addSql('ALTER TABLE import_workflow_customs MODIFY value_added_tax DECIMAL(15,2) DEFAULT NULL'); + $this->addSql('ALTER TABLE import_workflow_customs MODIFY other_charges DECIMAL(15,2) DEFAULT NULL'); + $this->addSql('ALTER TABLE import_workflow_customs MODIFY total_customs_charges DECIMAL(15,2) DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // ImportWorkflow table - exchange rate + $this->addSql('ALTER TABLE import_workflow MODIFY exchange_rate VARCHAR(255) DEFAULT NULL'); + + // ImportWorkflowItem table - monetary fields + $this->addSql('ALTER TABLE import_workflow_item MODIFY unit_price VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE import_workflow_item MODIFY unit_price_irr VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE import_workflow_item MODIFY total_price VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE import_workflow_item MODIFY total_price_irr VARCHAR(255) DEFAULT NULL'); + + // ImportWorkflowPayment table - monetary fields + $this->addSql('ALTER TABLE import_workflow_payment MODIFY amount VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE import_workflow_payment MODIFY amount_irr VARCHAR(255) DEFAULT NULL'); + + // ImportWorkflowCustoms table - monetary fields + $this->addSql('ALTER TABLE import_workflow_customs MODIFY customs_duty VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE import_workflow_customs MODIFY value_added_tax VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE import_workflow_customs MODIFY other_charges VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE import_workflow_customs MODIFY total_customs_charges VARCHAR(255) DEFAULT NULL'); + } +} diff --git a/hesabixCore/src/Controller/AdminController.php b/hesabixCore/src/Controller/AdminController.php index bdf2c16..38651bd 100644 --- a/hesabixCore/src/Controller/AdminController.php +++ b/hesabixCore/src/Controller/AdminController.php @@ -360,6 +360,9 @@ class AdminController extends AbstractController 'passChequeInput' => $registryMGR->get('sms', 'plugAccproPassChequeInput'), 'rejectChequeInput' => $registryMGR->get('sms', 'plugAccproRejectChequeInput') ]; + $resp['plugWarranty'] = [ + 'sendSerial' => $registryMGR->get('sms', 'plugWarrantySendSerial'), + ]; return $this->json($resp); } @@ -431,7 +434,10 @@ class AdminController extends AbstractController if (array_key_exists('rejectChequeInput', $params['plugAccpro'])) $registryMGR->update('sms', 'plugAccproRejectChequeInput', $params['plugAccpro']['rejectChequeInput'] ?? ''); } - + if (array_key_exists('plugWarranty', $params)) { + if (array_key_exists('sendSerial', $params['plugWarranty'])) + $registryMGR->update('sms', 'plugWarrantySendSerial', $params['plugWarranty']['sendSerial'] ?? ''); + } return $this->json(JsonResp::success()); } diff --git a/hesabixCore/src/Controller/ApprovalController.php b/hesabixCore/src/Controller/ApprovalController.php index 5307646..6cf9686 100644 --- a/hesabixCore/src/Controller/ApprovalController.php +++ b/hesabixCore/src/Controller/ApprovalController.php @@ -653,22 +653,23 @@ class ApprovalController extends AbstractController } $approversMap = [ - 'sell' => 'getApproverSellInvoice', - 'buy' => 'getApproverBuyInvoice', - 'storeroom' => 'getApproverWarehouseTransfer', - 'rfsell' => 'getApproverReturnSell', - 'rfbuy' => 'getApproverReturnBuy', - 'sell_receive' => 'getApproverReceiveFromPersons', - 'buy_send' => 'getApproverPayToPersons', - 'hesabdari' => 'getApproverAccountingDocs', - 'transfer' => 'getApproverBankTransfers', + 'getApproverSellInvoice' => ['sell'], + 'getApproverBuyInvoice' => ['buy'], + 'getApproverWarehouseTransfer' => ['storeroom'], + 'getApproverReturnSell' => ['rfsell'], + 'getApproverReturnBuy' => ['rfbuy'], + 'getApproverReceiveFromPersons' => ['person_receive'], + 'getApproverPayToPersons' => ['person_send'], + 'getApproverAccountingDocs' => ['calc'], + 'getApproverBankTransfers' => ['transfer'], ]; - if (!isset($approversMap[$documentType])) { - return false; + foreach ($approversMap as $method => $types) { + if (in_array($documentType, $types, true)) { + return $business->$method() === $user->getEmail(); + } } - $method = $approversMap[$documentType]; - return $business->$method() === $user->getEmail(); + return false; } } diff --git a/hesabixCore/src/Controller/Plugins/PlugImportWorkflowController.php b/hesabixCore/src/Controller/Plugins/PlugImportWorkflowController.php index f4465bd..51dd3d5 100644 --- a/hesabixCore/src/Controller/Plugins/PlugImportWorkflowController.php +++ b/hesabixCore/src/Controller/Plugins/PlugImportWorkflowController.php @@ -64,7 +64,7 @@ class PlugImportWorkflowController extends AbstractController 'status' => $workflow->getStatus(), 'dateSubmit' => $workflow->getDateSubmit(), 'supplierName' => $workflow->getSupplierName(), - 'totalAmount' => $workflow->getTotalAmount(), + 'totalAmount' => $workflow->getComputedTotalAmount(), 'currency' => $workflow->getCurrency(), 'submitter' => $workflow->getSubmitter()->getFullName() ]; @@ -137,10 +137,8 @@ class PlugImportWorkflowController extends AbstractController $workflow->setSupplierAddress($data['supplierAddress'] ?? ''); $workflow->setSupplierPhone($data['supplierPhone'] ?? ''); $workflow->setSupplierEmail($data['supplierEmail'] ?? ''); - $workflow->setTotalAmount($data['totalAmount'] ?? ''); $workflow->setCurrency($data['currency'] ?? ''); - $workflow->setExchangeRate($data['exchangeRate'] ?? ''); - $workflow->setTotalAmountIRR($data['totalAmountIRR'] ?? ''); + $workflow->setExchangeRate(isset($data['exchangeRate']) && $data['exchangeRate'] !== '' ? $data['exchangeRate'] : null); $workflow->setStatus('draft'); $entityManager->persist($workflow); @@ -242,10 +240,8 @@ class PlugImportWorkflowController extends AbstractController 'supplierAddress' => $workflow->getSupplierAddress(), 'supplierPhone' => $workflow->getSupplierPhone(), 'supplierEmail' => $workflow->getSupplierEmail(), - 'totalAmount' => $workflow->getTotalAmount(), 'currency' => $workflow->getCurrency(), 'exchangeRate' => $workflow->getExchangeRate(), - 'totalAmountIRR' => $workflow->getTotalAmountIRR(), 'submitter' => $workflow->getSubmitter()->getFullName(), 'items' => [], 'payments' => [], @@ -632,10 +628,10 @@ class PlugImportWorkflowController extends AbstractController $c->setDeclarationNumber($data['declarationNumber'] ?? ''); $c->setCustomsCode($data['customsCode'] ?? null); $c->setClearanceDate(isset($data['clearanceDate']) ? ($this->jalaliToGregorian($data['clearanceDate']) ?? null) : null); - $c->setCustomsDuty(isset($data['customsDuty']) ? (string)$data['customsDuty'] : null); - $c->setValueAddedTax(isset($data['valueAddedTax']) ? (string)$data['valueAddedTax'] : null); - $c->setOtherCharges(isset($data['otherCharges']) ? (string)$data['otherCharges'] : null); - $c->setTotalCustomsCharges(isset($data['totalCustomsCharges']) ? (string)$data['totalCustomsCharges'] : null); + $c->setCustomsDuty(isset($data['customsDuty']) && $data['customsDuty'] !== '' ? (string)$data['customsDuty'] : null); + $c->setValueAddedTax(isset($data['valueAddedTax']) && $data['valueAddedTax'] !== '' ? (string)$data['valueAddedTax'] : null); + $c->setOtherCharges(isset($data['otherCharges']) && $data['otherCharges'] !== '' ? (string)$data['otherCharges'] : null); + $c->setTotalCustomsCharges(isset($data['totalCustomsCharges']) && $data['totalCustomsCharges'] !== '' ? (string)$data['totalCustomsCharges'] : null); $c->setCustomsBroker($data['customsBroker'] ?? null); $c->setCustomsBrokerPhone($data['customsBrokerPhone'] ?? null); $c->setCustomsBrokerEmail($data['customsBrokerEmail'] ?? null); @@ -665,10 +661,10 @@ class PlugImportWorkflowController extends AbstractController if (isset($data['declarationNumber'])) $c->setDeclarationNumber($data['declarationNumber']); if (isset($data['customsCode'])) $c->setCustomsCode($data['customsCode']); if (isset($data['clearanceDate'])) $c->setClearanceDate($this->jalaliToGregorian($data['clearanceDate']) ?? null); - if (isset($data['customsDuty'])) $c->setCustomsDuty((string)$data['customsDuty']); - if (isset($data['valueAddedTax'])) $c->setValueAddedTax((string)$data['valueAddedTax']); - if (isset($data['otherCharges'])) $c->setOtherCharges((string)$data['otherCharges']); - if (isset($data['totalCustomsCharges'])) $c->setTotalCustomsCharges((string)$data['totalCustomsCharges']); + if (isset($data['customsDuty'])) $c->setCustomsDuty($data['customsDuty'] !== '' ? (string)$data['customsDuty'] : null); + if (isset($data['valueAddedTax'])) $c->setValueAddedTax($data['valueAddedTax'] !== '' ? (string)$data['valueAddedTax'] : null); + if (isset($data['otherCharges'])) $c->setOtherCharges($data['otherCharges'] !== '' ? (string)$data['otherCharges'] : null); + if (isset($data['totalCustomsCharges'])) $c->setTotalCustomsCharges($data['totalCustomsCharges'] !== '' ? (string)$data['totalCustomsCharges'] : null); if (isset($data['customsBroker'])) $c->setCustomsBroker($data['customsBroker']); if (isset($data['customsBrokerPhone'])) $c->setCustomsBrokerPhone($data['customsBrokerPhone']); if (isset($data['customsBrokerEmail'])) $c->setCustomsBrokerEmail($data['customsBrokerEmail']); @@ -714,9 +710,9 @@ class PlugImportWorkflowController extends AbstractController $p = new ImportWorkflowPayment(); $p->setImportWorkflow($workflow); $p->setType($data['type'] ?? 'other'); - $p->setAmount((string)($data['amount'] ?? '0')); + $p->setAmount(($data['amount'] ?? '0')); $p->setCurrency($data['currency'] ?? 'IRR'); - $p->setAmountIRR(isset($data['amountIRR']) ? (string)$data['amountIRR'] : null); + $p->setAmountIRR(isset($data['amountIRR']) && $data['amountIRR'] !== '' ? (string)$data['amountIRR'] : null); $p->setPaymentDate($this->jalaliToGregorian($data['paymentDate']) ?? date('Y-m-d')); $p->setReferenceNumber($data['referenceNumber'] ?? null); $p->setBankName($data['bankName'] ?? null); @@ -749,7 +745,7 @@ class PlugImportWorkflowController extends AbstractController if (isset($data['type'])) $p->setType($data['type']); if (isset($data['amount'])) $p->setAmount((string)$data['amount']); if (isset($data['currency'])) $p->setCurrency($data['currency']); - if (isset($data['amountIRR'])) $p->setAmountIRR((string)$data['amountIRR']); + if (isset($data['amountIRR'])) $p->setAmountIRR($data['amountIRR'] !== '' ? (string)$data['amountIRR'] : null); if (isset($data['paymentDate'])) $p->setPaymentDate($this->jalaliToGregorian($data['paymentDate']) ?? date('Y-m-d')); if (isset($data['referenceNumber'])) $p->setReferenceNumber($data['referenceNumber']); if (isset($data['bankName'])) $p->setBankName($data['bankName']); @@ -818,10 +814,28 @@ class PlugImportWorkflowController extends AbstractController $item->setModel($data['model'] ?? null); $item->setOriginCountry($data['originCountry'] ?? null); $item->setQuantity($data['quantity'] ?? '0'); - $item->setUnitPrice($data['unitPrice'] ?? null); - $item->setUnitPriceIRR($data['unitPriceIRR'] ?? null); - $item->setTotalPrice($data['totalPrice'] ?? null); - $item->setTotalPriceIRR($data['totalPriceIRR'] ?? null); + $item->setUnitPrice(isset($data['unitPrice']) && $data['unitPrice'] !== '' ? $data['unitPrice'] : null); + + // محاسبه قیمت واحد ریالی بر اساس نرخ ارز پرونده + $unitPrice = (float) ($data['unitPrice'] ?? 0); + $exchangeRate = (float) ($workflow->getExchangeRate() ?? 0); + $currency = $workflow->getCurrency(); + + if ($currency === 'IRR') { + $unitPriceIRR = $unitPrice; + } else { + $unitPriceIRR = $unitPrice * $exchangeRate; + } + $item->setUnitPriceIRR((string) round($unitPriceIRR)); + + // محاسبه قیمت کل + $quantity = (float) ($data['quantity'] ?? 0); + $totalPrice = $quantity * $unitPrice; + $item->setTotalPrice((string) round($totalPrice)); + + // محاسبه قیمت کل ریالی + $totalPriceIRR = $quantity * $unitPriceIRR; + $item->setTotalPriceIRR((string) round($totalPriceIRR)); $item->setWeight($data['weight'] ?? null); $item->setVolume($data['volume'] ?? null); $item->setDescription($data['description'] ?? null); @@ -869,10 +883,30 @@ class PlugImportWorkflowController extends AbstractController if (isset($data['model'])) $item->setModel($data['model']); if (isset($data['originCountry'])) $item->setOriginCountry($data['originCountry']); if (isset($data['quantity'])) $item->setQuantity($data['quantity']); - if (isset($data['unitPrice'])) $item->setUnitPrice($data['unitPrice']); - if (isset($data['unitPriceIRR'])) $item->setUnitPriceIRR($data['unitPriceIRR']); - if (isset($data['totalPrice'])) $item->setTotalPrice($data['totalPrice']); - if (isset($data['totalPriceIRR'])) $item->setTotalPriceIRR($data['totalPriceIRR']); + if (isset($data['unitPrice'])) { + $item->setUnitPrice($data['unitPrice'] !== '' ? $data['unitPrice'] : null); + + // محاسبه مجدد قیمت واحد ریالی بر اساس نرخ ارز پرونده + $unitPrice = (float) $data['unitPrice']; + $exchangeRate = (float) ($workflow->getExchangeRate() ?? 0); + $currency = $workflow->getCurrency(); + + if ($currency === 'IRR') { + $unitPriceIRR = $unitPrice; + } else { + $unitPriceIRR = $unitPrice * $exchangeRate; + } + $item->setUnitPriceIRR((string) round($unitPriceIRR)); + + // محاسبه مجدد قیمت کل + $quantity = (float) $item->getQuantity(); + $totalPrice = $quantity * $unitPrice; + $item->setTotalPrice((string) round($totalPrice)); + + // محاسبه مجدد قیمت کل ریالی + $totalPriceIRR = $quantity * $unitPriceIRR; + $item->setTotalPriceIRR((string) round($totalPriceIRR)); + } if (isset($data['weight'])) $item->setWeight($data['weight']); if (isset($data['volume'])) $item->setVolume($data['volume']); if (isset($data['description'])) $item->setDescription($data['description']); @@ -942,10 +976,9 @@ class PlugImportWorkflowController extends AbstractController if (isset($data['supplierAddress'])) $workflow->setSupplierAddress($data['supplierAddress']); if (isset($data['supplierPhone'])) $workflow->setSupplierPhone($data['supplierPhone']); if (isset($data['supplierEmail'])) $workflow->setSupplierEmail($data['supplierEmail']); - if (isset($data['totalAmount'])) $workflow->setTotalAmount($data['totalAmount']); + if (isset($data['currency'])) $workflow->setCurrency($data['currency']); - if (isset($data['exchangeRate'])) $workflow->setExchangeRate($data['exchangeRate']); - if (isset($data['totalAmountIRR'])) $workflow->setTotalAmountIRR($data['totalAmountIRR']); + if (isset($data['exchangeRate'])) $workflow->setExchangeRate($data['exchangeRate'] !== '' ? $data['exchangeRate'] : null); if (isset($data['status'])) $workflow->setStatus($data['status']); $workflow->setDateMod(date('Y-m-d H:i:s')); diff --git a/hesabixCore/src/Entity/ImportWorkflow.php b/hesabixCore/src/Entity/ImportWorkflow.php index eef7f9e..6bc5e30 100644 --- a/hesabixCore/src/Entity/ImportWorkflow.php +++ b/hesabixCore/src/Entity/ImportWorkflow.php @@ -60,18 +60,12 @@ class ImportWorkflow #[ORM\Column(length: 255, nullable: true)] private ?string $supplierEmail = null; - #[ORM\Column(length: 255, nullable: true)] - private ?string $totalAmount = null; - #[ORM\Column(length: 255, nullable: true)] private ?string $currency = null; - #[ORM\Column(length: 255, nullable: true)] + #[ORM\Column(type: Types::DECIMAL, precision: 15, scale: 2, nullable: true)] private ?string $exchangeRate = null; - #[ORM\Column(length: 255, nullable: true)] - private ?string $totalAmountIRR = null; - #[ORM\OneToMany(mappedBy: 'importWorkflow', targetEntity: ImportWorkflowItem::class, orphanRemoval: true)] private Collection $items; @@ -250,17 +244,6 @@ class ImportWorkflow return $this; } - public function getTotalAmount(): ?string - { - return $this->totalAmount; - } - - public function setTotalAmount(?string $totalAmount): static - { - $this->totalAmount = $totalAmount; - return $this; - } - public function getCurrency(): ?string { return $this->currency; @@ -283,17 +266,6 @@ class ImportWorkflow return $this; } - public function getTotalAmountIRR(): ?string - { - return $this->totalAmountIRR; - } - - public function setTotalAmountIRR(?string $totalAmountIRR): static - { - $this->totalAmountIRR = $totalAmountIRR; - return $this; - } - public function getItems(): Collection { return $this->items; diff --git a/hesabixCore/src/Entity/ImportWorkflowCustoms.php b/hesabixCore/src/Entity/ImportWorkflowCustoms.php index e8c2cd5..ba61742 100644 --- a/hesabixCore/src/Entity/ImportWorkflowCustoms.php +++ b/hesabixCore/src/Entity/ImportWorkflowCustoms.php @@ -29,16 +29,16 @@ class ImportWorkflowCustoms #[ORM\Column(length: 255, nullable: true)] private ?string $clearanceDate = null; - #[ORM\Column(length: 255, nullable: true)] + #[ORM\Column(type: Types::DECIMAL, precision: 15, scale: 2, nullable: true)] private ?string $customsDuty = null; - #[ORM\Column(length: 255, nullable: true)] + #[ORM\Column(type: Types::DECIMAL, precision: 15, scale: 2, nullable: true)] private ?string $valueAddedTax = null; - #[ORM\Column(length: 255, nullable: true)] + #[ORM\Column(type: Types::DECIMAL, precision: 15, scale: 2, nullable: true)] private ?string $otherCharges = null; - #[ORM\Column(length: 255, nullable: true)] + #[ORM\Column(type: Types::DECIMAL, precision: 15, scale: 2, nullable: true)] private ?string $totalCustomsCharges = null; #[ORM\Column(length: 255, nullable: true)] diff --git a/hesabixCore/src/Entity/ImportWorkflowItem.php b/hesabixCore/src/Entity/ImportWorkflowItem.php index aa3dd68..33fa4b6 100644 --- a/hesabixCore/src/Entity/ImportWorkflowItem.php +++ b/hesabixCore/src/Entity/ImportWorkflowItem.php @@ -43,16 +43,16 @@ class ImportWorkflowItem #[ORM\Column(length: 255)] private ?string $quantity = null; - #[ORM\Column(length: 255, nullable: true)] + #[ORM\Column(type: Types::DECIMAL, precision: 15, scale: 2, nullable: true)] private ?string $unitPrice = null; - #[ORM\Column(length: 255, nullable: true)] + #[ORM\Column(type: Types::DECIMAL, precision: 15, scale: 2, nullable: true)] private ?string $unitPriceIRR = null; - #[ORM\Column(length: 255, nullable: true)] + #[ORM\Column(type: Types::DECIMAL, precision: 15, scale: 2, nullable: true)] private ?string $totalPrice = null; - #[ORM\Column(length: 255, nullable: true)] + #[ORM\Column(type: Types::DECIMAL, precision: 15, scale: 2, nullable: true)] private ?string $totalPriceIRR = null; #[ORM\Column(length: 255, nullable: true)] diff --git a/hesabixCore/src/Entity/ImportWorkflowPayment.php b/hesabixCore/src/Entity/ImportWorkflowPayment.php index 80eec3a..fe72698 100644 --- a/hesabixCore/src/Entity/ImportWorkflowPayment.php +++ b/hesabixCore/src/Entity/ImportWorkflowPayment.php @@ -23,13 +23,13 @@ class ImportWorkflowPayment #[ORM\Column(length: 255)] private ?string $type = null; - #[ORM\Column(length: 255)] + #[ORM\Column(type: Types::DECIMAL, precision: 15, scale: 2)] private ?string $amount = null; #[ORM\Column(length: 255, nullable: true)] private ?string $currency = null; - #[ORM\Column(length: 255, nullable: true)] + #[ORM\Column(type: Types::DECIMAL, precision: 15, scale: 2, nullable: true)] private ?string $amountIRR = null; #[ORM\Column(length: 255)] diff --git a/hesabixCore/src/Service/FileStorage.php b/hesabixCore/src/Service/FileStorage.php index 938a4cb..f323ddc 100644 --- a/hesabixCore/src/Service/FileStorage.php +++ b/hesabixCore/src/Service/FileStorage.php @@ -15,7 +15,7 @@ class FileStorage { $safeOriginal = preg_replace('/[^A-Za-z0-9_.-]/', '_', $file->getClientOriginalName()); $relativeDir = 'storage/' . trim($businessId) . '/' . trim($context); - $absDir = rtrim($this->kernel->getProjectDir(), '/').'/var/' . $relativeDir; + $absDir = rtrim($this->kernel->getProjectDir(), '/').'/../hesabixArchive/' . $relativeDir; if (!is_dir($absDir)) { @mkdir($absDir, 0775, true); } @@ -35,7 +35,7 @@ class FileStorage public function absolutePath(string $relativePath): string { $relativePath = ltrim($relativePath, '/'); - return rtrim($this->kernel->getProjectDir(), '/').'/var/' . $relativePath; + return rtrim($this->kernel->getProjectDir(), '/').'/../hesabixArchive/' . $relativePath; } } diff --git a/webUI/src/components/plugins/import-workflow/ImportWorkflowCreateDialog.vue b/webUI/src/components/plugins/import-workflow/ImportWorkflowCreateDialog.vue index e13d861..339ab04 100644 --- a/webUI/src/components/plugins/import-workflow/ImportWorkflowCreateDialog.vue +++ b/webUI/src/components/plugins/import-workflow/ImportWorkflowCreateDialog.vue @@ -75,18 +75,7 @@ - - - - + - + - + + نکته: مبلغ کل پرونده به صورت خودکار از جمع اقلام محاسبه میشود و نیازی به وارد کردن دستی نیست. + @@ -174,10 +166,8 @@ const formData = ref({ supplierPhone: '', supplierEmail: '', supplierAddress: '', - totalAmount: '', currency: 'USD', exchangeRate: '', - totalAmountIRR: '', description: '' }) @@ -213,35 +203,34 @@ const rules = { maxExchangeRate: (value) => !value || parseFloat(value) <= 999999 || 'نرخ تبدیل نباید بیشتر از 999,999 باشد' } -const parseMoneyInput = (val) => { - if (val === null || val === undefined) return 0 - const cleaned = String(val).replace(/,/g, '').replace(/[^\d.-]/g, '') - const num = Number(cleaned) - return Number.isFinite(num) ? num : 0 +const parseMoney = (val) => { + if (val === null || val === undefined || val === '') return 0 + const clean = String(val).replace(/,/g, '') + const num = parseFloat(clean) + return isNaN(num) ? 0 : parseFloat(num.toFixed(2)) } -const onMoneyInput = (field, value) => { - const numeric = parseMoneyInput(value) - formData.value[field] = numeric +const formatMoneyTyping = (val) => { + if (val === null || val === undefined || val === '') return '' + const str = String(val).replace(/,/g, '') + if (str === '') return '' + const parts = str.split('.') + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',') + return parts.join('.') +} + +const onMoneyInput = (field, val) => { + formData.value[field] = parseMoney(val) } const formatMoney = (value) => { const numericValue = Number(value) || 0 return numericValue - .toFixed(0) + .toFixed(2) .replace(/\B(?=(\d{3})+(?!\d))/g, ',') } -watch([ - () => formData.value.totalAmount, - () => formData.value.exchangeRate, - () => formData.value.currency -], ([newTotalAmount, newExchangeRate, currency]) => { - const total = parseMoneyInput(newTotalAmount) - const rate = currency === 'IRR' ? 1 : parseMoneyInput(newExchangeRate) - const result = Math.round(total * rate) - formData.value.totalAmountIRR = isNaN(result) ? 0 : result -}, { immediate: true }) +// مبلغ کل به صورت محاسباتی از اقلام محاسبه میشود // Methods const create = async () => { @@ -287,10 +276,8 @@ const resetForm = () => { supplierPhone: '', supplierEmail: '', supplierAddress: '', - totalAmount: '', currency: 'USD', exchangeRate: '', - totalAmountIRR: '', description: '' } if (form.value) { diff --git a/webUI/src/components/plugins/import-workflow/ImportWorkflowCustoms.vue b/webUI/src/components/plugins/import-workflow/ImportWorkflowCustoms.vue index f93ac61..aef2bd1 100644 --- a/webUI/src/components/plugins/import-workflow/ImportWorkflowCustoms.vue +++ b/webUI/src/components/plugins/import-workflow/ImportWorkflowCustoms.vue @@ -27,6 +27,12 @@ ریال + + + + {{ formatDate(item.clearanceDate) }} + + @@ -261,22 +270,30 @@ const rules = { } // Helpers for money formatting/parse and LTR input -const parseMoneyInput = (val) => { - if (val === null || val === undefined) return 0 - const cleaned = String(val).replace(/,/g, '').replace(/[^\d.-]/g, '') - const num = Number(cleaned) - return Number.isFinite(num) ? num : 0 +const parseMoney = (val) => { + if (val === null || val === undefined || val === '') return 0 + const clean = String(val).replace(/,/g, '') + const num = parseFloat(clean) + return isNaN(num) ? 0 : parseFloat(num.toFixed(2)) } -const onMoneyInput = (field, value) => { - const numeric = parseMoneyInput(value) - formData.value[field] = numeric +const formatMoneyTyping = (val) => { + if (val === null || val === undefined || val === '') return '' + const str = String(val).replace(/,/g, '') + if (str === '') return '' + const parts = str.split('.') + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',') + return parts.join('.') +} + +const onMoneyInput = (field, val) => { + formData.value[field] = parseMoney(val) } const formatMoney = (value) => { const numericValue = Number(value) || 0 return numericValue - .toFixed(0) + .toFixed(2) .replace(/\B(?=(\d{3})+(?!\d))/g, ',') } @@ -391,6 +408,11 @@ const formatNumber = (number) => { if (!number) return '0' return new Intl.NumberFormat('fa-IR').format(number) } + +const formatDate = (date) => { + if (!date) return '-' + return new Date(date).toLocaleDateString('fa-IR') +} - - - diff --git a/webUI/src/components/plugins/import-workflow/ImportWorkflowPayments.vue b/webUI/src/components/plugins/import-workflow/ImportWorkflowPayments.vue index f2cc8fc..adc9136 100644 --- a/webUI/src/components/plugins/import-workflow/ImportWorkflowPayments.vue +++ b/webUI/src/components/plugins/import-workflow/ImportWorkflowPayments.vue @@ -3,30 +3,15 @@ پرداختها - + افزودن پرداخت - + - + {{ getTypeText(item.type) }} @@ -40,16 +25,13 @@ - {{ formatNumber(item.amountIRR) }} + {{ formatNumber(Number(item.amount) * Number(props.exchangeRate)) }} ریال - + {{ getStatusText(item.status) }} @@ -59,19 +41,8 @@ - - + + @@ -89,113 +60,65 @@ - + - + - - + + @blur="formData.amount = parseMoney(formData.amount)"> - - + + - - + + + + + نکته: مبلغ ریالی به صورت خودکار بر اساس نرخ ارز پرونده محاسبه میشود. + - + - + - + - + - + - + - + @@ -205,12 +128,7 @@ لغو - + {{ editingPayment ? 'ویرایش' : 'افزودن' }} @@ -236,7 +154,7 @@