diff --git a/hesabixCore/migrations/Version20241220000000.php b/hesabixCore/migrations/Version20241220000000.php deleted file mode 100644 index 3d12ad1..0000000 --- a/hesabixCore/migrations/Version20241220000000.php +++ /dev/null @@ -1,40 +0,0 @@ -addSql('ALTER TABLE chat_channel ADD member_count INT NOT NULL DEFAULT 0'); - - // Update existing channels with correct member count - $this->addSql(' - UPDATE chat_channel c - SET member_count = ( - SELECT COUNT(*) - FROM chat_channel_member m - WHERE m.channel_id = c.id AND m.is_active = 1 - ) - '); - } - - public function down(Schema $schema): void - { - $this->addSql('ALTER TABLE chat_channel DROP member_count'); - } -} \ No newline at end of file diff --git a/hesabixCore/migrations/Version20250809100001.php b/hesabixCore/migrations/Version20250809100001.php deleted file mode 100644 index afc4739..0000000 --- a/hesabixCore/migrations/Version20250809100001.php +++ /dev/null @@ -1,30 +0,0 @@ -addSql('CREATE TABLE custom_invoice_template (id INT AUTO_INCREMENT NOT NULL, bid_id INT NOT NULL, submitter_id INT NOT NULL, name VARCHAR(255) NOT NULL, is_public TINYINT(1) NOT NULL, code LONGTEXT NOT NULL, INDEX IDX_CUSTOM_INV_TPL_BID (bid_id), INDEX IDX_CUSTOM_INV_TPL_SUBMITTER (submitter_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); - $this->addSql('ALTER TABLE custom_invoice_template ADD CONSTRAINT FK_CUSTOM_INV_TPL_BID FOREIGN KEY (bid_id) REFERENCES business (id)'); - $this->addSql('ALTER TABLE custom_invoice_template ADD CONSTRAINT FK_CUSTOM_INV_TPL_SUBMITTER FOREIGN KEY (submitter_id) REFERENCES `user` (id)'); - } - - public function down(Schema $schema): void - { - $this->addSql('ALTER TABLE custom_invoice_template DROP FOREIGN KEY FK_CUSTOM_INV_TPL_BID'); - $this->addSql('ALTER TABLE custom_invoice_template DROP FOREIGN KEY FK_CUSTOM_INV_TPL_SUBMITTER'); - $this->addSql('DROP TABLE custom_invoice_template'); - } -} \ No newline at end of file diff --git a/hesabixCore/migrations/Version20250806183700.php b/hesabixCore/migrations/Version20250811113332.php similarity index 64% rename from hesabixCore/migrations/Version20250806183700.php rename to hesabixCore/migrations/Version20250811113332.php index 7e7d4d4..b46c836 100644 --- a/hesabixCore/migrations/Version20250806183700.php +++ b/hesabixCore/migrations/Version20250811113332.php @@ -10,22 +10,26 @@ use Doctrine\Migrations\AbstractMigration; /** * Auto-generated Migration: Please modify to your needs! */ -final class Version20250806183700 extends AbstractMigration +final class Version20250811113332 extends AbstractMigration { public function getDescription(): string { - return 'Add warehouseManager field to permission table'; + return ''; } public function up(Schema $schema): void { // this up() migration is auto-generated, please modify it to your needs - $this->addSql('ALTER TABLE permission ADD warehouse_manager TINYINT(1) DEFAULT NULL'); + $this->addSql(<<<'SQL' + ALTER TABLE person ADD require_two_step TINYINT(1) DEFAULT NULL + SQL); } public function down(Schema $schema): void { // this down() migration is auto-generated, please modify it to your needs - $this->addSql('ALTER TABLE permission DROP warehouse_manager'); + $this->addSql(<<<'SQL' + ALTER TABLE person DROP require_two_step + SQL); } } diff --git a/hesabixCore/src/Cog/PersonService.php b/hesabixCore/src/Cog/PersonService.php index 61c0ecd..7895d6c 100644 --- a/hesabixCore/src/Cog/PersonService.php +++ b/hesabixCore/src/Cog/PersonService.php @@ -288,6 +288,10 @@ class PersonService if (isset($params['shenasemeli'])) $person->setShenasemeli($params['shenasemeli']); if (isset($params['company'])) $person->setCompany($params['company']); if (isset($params['tags'])) $person->setTags($params['tags']); + if (isset($params['requireTwoStep'])) { + error_log("Setting requireTwoStep: " . var_export($params['requireTwoStep'], true)); + $person->setRequireTwoStep((bool)$params['requireTwoStep']); + } if (array_key_exists('prelabel', $params)) { if ($params['prelabel'] != '') { $prelabel = $em->getRepository(\App\Entity\PersonPrelabel::class)->findOneBy(['label' => $params['prelabel']]); diff --git a/hesabixCore/src/Controller/SellController.php b/hesabixCore/src/Controller/SellController.php index 07067a0..e9dbf80 100644 --- a/hesabixCore/src/Controller/SellController.php +++ b/hesabixCore/src/Controller/SellController.php @@ -324,7 +324,8 @@ class SellController extends AbstractController // Two-step approval: اگر پرمیشن کسب‌وکار تأیید دو مرحله‌ای فروش را الزامی کرده باشد $permission = $entityManager->getRepository(\App\Entity\Permission::class)->findOneBy(['bid' => $acc['bid'], 'user' => $acc['user']]); - if ($permission && $permission->isRequireTwoStepSell()) { + $personRequire = $person && method_exists($person, 'isRequireTwoStep') ? (bool)$person->isRequireTwoStep() : false; + if (($permission && $permission->isRequireTwoStepSell()) || $personRequire) { $doc->setStatus('pending_approval'); } else { $doc->setStatus('approved'); @@ -1320,7 +1321,8 @@ class SellController extends AbstractController // Two-step approval برای دریافت/پرداخت $permission = $entityManager->getRepository(\App\Entity\Permission::class)->findOneBy(['bid' => $acc['bid'], 'user' => $acc['user']]); - if ($permission && $permission->isRequireTwoStepPayment()) { + $personRequire = $person && method_exists($person, 'isRequireTwoStep') ? (bool)$person->isRequireTwoStep() : false; + if (($permission && $permission->isRequireTwoStepPayment()) || $personRequire) { $paymentDoc->setStatus('pending_approval'); } else { $paymentDoc->setStatus('approved'); diff --git a/hesabixCore/src/Controller/StoreroomController.php b/hesabixCore/src/Controller/StoreroomController.php index 911547f..673cad1 100644 --- a/hesabixCore/src/Controller/StoreroomController.php +++ b/hesabixCore/src/Controller/StoreroomController.php @@ -576,7 +576,8 @@ class StoreroomController extends AbstractController $entityManager->flush(); // اگر تأیید دو مرحله‌ای حواله فعال باشد، وضعیت را pending_approval بگذاریم $permission = $entityManager->getRepository(\App\Entity\Permission::class)->findOneBy(['bid' => $acc['bid'], 'user' => $acc['user']]); - if ($permission && $permission->isRequireTwoStepStore()) { + $personRequire = $person && method_exists($person, 'isRequireTwoStep') ? (bool)$person->isRequireTwoStep() : false; + if (($permission && $permission->isRequireTwoStepStore()) || $personRequire) { $ticket->setStatus('pending_approval'); $entityManager->persist($ticket); $entityManager->flush(); diff --git a/hesabixCore/src/Entity/Person.php b/hesabixCore/src/Entity/Person.php index d2733ab..19ac6cb 100644 --- a/hesabixCore/src/Entity/Person.php +++ b/hesabixCore/src/Entity/Person.php @@ -161,6 +161,9 @@ class Person #[ORM\Column(type: Types::TEXT, nullable: true)] private ?string $tags = null; + #[ORM\Column(nullable: true)] + private ?bool $requireTwoStep = null; + public function __construct() { $this->hesabdariRows = new ArrayCollection(); @@ -913,4 +916,15 @@ class Person $this->tags = $tags; return $this; } + + public function isRequireTwoStep(): ?bool + { + return $this->requireTwoStep; + } + + public function setRequireTwoStep(?bool $requireTwoStep): self + { + $this->requireTwoStep = $requireTwoStep; + return $this; + } } diff --git a/webUI/src/components/plugins/import-workflow/ImportWorkflowCreateDialog.vue b/webUI/src/components/plugins/import-workflow/ImportWorkflowCreateDialog.vue new file mode 100644 index 0000000..e13d861 --- /dev/null +++ b/webUI/src/components/plugins/import-workflow/ImportWorkflowCreateDialog.vue @@ -0,0 +1,306 @@ + + + + diff --git a/webUI/src/components/plugins/import-workflow/ImportWorkflowCustoms.vue b/webUI/src/components/plugins/import-workflow/ImportWorkflowCustoms.vue new file mode 100644 index 0000000..f3208ce --- /dev/null +++ b/webUI/src/components/plugins/import-workflow/ImportWorkflowCustoms.vue @@ -0,0 +1,423 @@ + + + + + \ No newline at end of file diff --git a/webUI/src/components/plugins/import-workflow/ImportWorkflowDocuments.vue b/webUI/src/components/plugins/import-workflow/ImportWorkflowDocuments.vue new file mode 100644 index 0000000..5f023c7 --- /dev/null +++ b/webUI/src/components/plugins/import-workflow/ImportWorkflowDocuments.vue @@ -0,0 +1,424 @@ + + + + + + + + diff --git a/webUI/src/components/plugins/import-workflow/ImportWorkflowItems.vue b/webUI/src/components/plugins/import-workflow/ImportWorkflowItems.vue new file mode 100644 index 0000000..f33e97b --- /dev/null +++ b/webUI/src/components/plugins/import-workflow/ImportWorkflowItems.vue @@ -0,0 +1,484 @@ + + + + + + + + diff --git a/webUI/src/components/plugins/import-workflow/ImportWorkflowPayments.vue b/webUI/src/components/plugins/import-workflow/ImportWorkflowPayments.vue new file mode 100644 index 0000000..4db9b96 --- /dev/null +++ b/webUI/src/components/plugins/import-workflow/ImportWorkflowPayments.vue @@ -0,0 +1,548 @@ + + + + + + + + diff --git a/webUI/src/components/plugins/import-workflow/ImportWorkflowShipping.vue b/webUI/src/components/plugins/import-workflow/ImportWorkflowShipping.vue new file mode 100644 index 0000000..6c9cbfd --- /dev/null +++ b/webUI/src/components/plugins/import-workflow/ImportWorkflowShipping.vue @@ -0,0 +1,394 @@ + + + + + + + + diff --git a/webUI/src/components/plugins/import-workflow/ImportWorkflowStages.vue b/webUI/src/components/plugins/import-workflow/ImportWorkflowStages.vue new file mode 100644 index 0000000..62454ea --- /dev/null +++ b/webUI/src/components/plugins/import-workflow/ImportWorkflowStages.vue @@ -0,0 +1,438 @@ + + + + + + + + diff --git a/webUI/src/router/index.ts b/webUI/src/router/index.ts index 389b00c..1bd05b2 100755 --- a/webUI/src/router/index.ts +++ b/webUI/src/router/index.ts @@ -1061,20 +1061,20 @@ const router = createRouter({ import('../views/acc/inquiry/panel.vue'), }, { - path: 'import-workflow/list', + path: 'plugins/import-workflow/list', name: 'import_workflow_list', component: () => - import('../views/ImportWorkflow/ImportWorkflowList.vue'), + import('../views/acc/plugins/import-workflow/list.vue'), meta: { 'title': 'مدیریت واردات کالا', 'login': true, } }, { - path: 'import-workflow/:id', + path: 'plugins/import-workflow/:id', name: 'import_workflow_detail', component: () => - import('../views/ImportWorkflow/ImportWorkflowDetail.vue'), + import('../views/acc/plugins/import-workflow/view.vue'), meta: { 'title': 'جزئیات پرونده واردات', 'login': true, diff --git a/webUI/src/views/acc/App.vue b/webUI/src/views/acc/App.vue index b1c6a57..80b531e 100755 --- a/webUI/src/views/acc/App.vue +++ b/webUI/src/views/acc/App.vue @@ -216,7 +216,7 @@ export default { { path: '/acc/plugins/tax/invoices/list', key: 'L', label: this.$t('drawer.tax_invoices'), ctrl: true, shift: true, permission: () => this.permissions.settings && this.isPluginActive('taxsettings') }, { path: '/acc/plugins/tax/settings', key: 'T', label: this.$t('drawer.tax_settings'), ctrl: true, shift: true, permission: () => this.permissions.settings && this.isPluginActive('taxsettings') }, { path: '/acc/plugins/custominvoice/templates', key: 'I', label: 'قالب‌های فاکتور', ctrl: true, shift: true, permission: () => this.permissions.settings && this.isPluginActive('custominvoice') }, - { path: '/acc/import-workflow/list', key: 'I', label: 'مدیریت واردات کالا', ctrl: true, shift: true, permission: () => this.permissions.importWorkflow }, + { path: '/acc/plugins/import-workflow', key: 'I', label: 'مدیریت واردات کالا', ctrl: true, shift: true, permission: () => this.permissions.importWorkflow }, ]; }, restorePermissions(shortcuts) { @@ -807,20 +807,21 @@ export default { {{ $t('drawer.services') }} - + - + لیست پرونده‌های واردات + {{ getShortcutKey('/acc/plugins/import-workflow/list') }} diff --git a/webUI/src/views/acc/persons/card.vue b/webUI/src/views/acc/persons/card.vue index 6fa709a..f077a48 100755 --- a/webUI/src/views/acc/persons/card.vue +++ b/webUI/src/views/acc/persons/card.vue @@ -11,6 +11,9 @@ {{ $t('dialog.banks_accounts') }} + + ویرایش شخص +