Merge branch 'master' of https://source.hesabix.ir/morrning/hesabixCore
This commit is contained in:
commit
45c03051a0
|
@ -29,7 +29,7 @@ class ApprovalController extends AbstractController
|
|||
EntityManagerInterface $entityManager
|
||||
): Response {
|
||||
try {
|
||||
$acc = $access->hasRole('settings');
|
||||
$acc = $access->hasRole('store');
|
||||
if (!$acc) {
|
||||
throw $this->createAccessDeniedException();
|
||||
}
|
||||
|
@ -82,6 +82,68 @@ class ApprovalController extends AbstractController
|
|||
}
|
||||
}
|
||||
|
||||
#[Route('/api/approval/unapprove/storeroom/{ticketCode}', name: 'api_approval_unapprove_storeroom', methods: ['POST'])]
|
||||
public function unapproveStoreroomTicket(
|
||||
$ticketCode,
|
||||
#[CurrentUser] ?User $user,
|
||||
Access $access,
|
||||
LogService $logService,
|
||||
EntityManagerInterface $entityManager
|
||||
): Response {
|
||||
try {
|
||||
$acc = $access->hasRole('store');
|
||||
if (!$acc) {
|
||||
throw $this->createAccessDeniedException();
|
||||
}
|
||||
|
||||
$business = $acc['bid'];
|
||||
$businessSettings = $entityManager->getRepository(Business::class)->find($business->getId());
|
||||
|
||||
if (!$businessSettings->isRequireTwoStepApproval()) {
|
||||
return $this->json(['success' => false, 'message' => 'تأیید دو مرحلهای فعال نیست']);
|
||||
}
|
||||
|
||||
$ticket = $entityManager->getRepository(\App\Entity\StoreroomTicket::class)->findOneBy([
|
||||
'code' => $ticketCode,
|
||||
'bid' => $business
|
||||
]);
|
||||
|
||||
if (!$ticket) {
|
||||
return $this->json(['success' => false, 'message' => 'حواله انبار یافت نشد']);
|
||||
}
|
||||
|
||||
$canApprove = $this->canUserApproveStoreroomTicket($user, $businessSettings);
|
||||
if (!$canApprove) {
|
||||
return $this->json(['success' => false, 'message' => 'شما مجوز تأیید این حواله را ندارید']);
|
||||
}
|
||||
|
||||
$ticket->setIsPreview(true);
|
||||
$ticket->setIsApproved(false);
|
||||
$ticket->setApprovedBy(null);
|
||||
|
||||
$entityManager->persist($ticket);
|
||||
$entityManager->flush();
|
||||
|
||||
$logService->insert(
|
||||
'لغو تأیید حواله انبار',
|
||||
"حواله انبار {$ticket->getCode()} توسط {$user->getFullName()} لغو تأیید شد",
|
||||
$user,
|
||||
$business
|
||||
);
|
||||
|
||||
return $this->json([
|
||||
'success' => true,
|
||||
'message' => 'حواله انبار با موفقیت لغو تأیید شد'
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'message' => 'خطا در لغو تأیید حواله انبار: ' . $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
#[Route('/api/approval/approve/sales/{docId}', name: 'api_approval_approve_sales', methods: ['POST'])]
|
||||
public function approveSalesInvoice(
|
||||
$docId,
|
||||
|
@ -91,7 +153,7 @@ class ApprovalController extends AbstractController
|
|||
EntityManagerInterface $entityManager
|
||||
): Response {
|
||||
try {
|
||||
$acc = $access->hasRole('settings');
|
||||
$acc = $access->hasRole('sell');
|
||||
if (!$acc) {
|
||||
throw $this->createAccessDeniedException();
|
||||
}
|
||||
|
@ -166,7 +228,7 @@ class ApprovalController extends AbstractController
|
|||
EntityManagerInterface $entityManager
|
||||
): Response {
|
||||
try {
|
||||
$acc = $access->hasRole('settings');
|
||||
$acc = $access->hasRole('sell');
|
||||
if (!$acc) {
|
||||
throw $this->createAccessDeniedException();
|
||||
}
|
||||
|
@ -250,7 +312,7 @@ class ApprovalController extends AbstractController
|
|||
EntityManagerInterface $entityManager
|
||||
): Response {
|
||||
try {
|
||||
$acc = $access->hasRole('settings');
|
||||
$acc = $access->hasRole('sell');
|
||||
if (!$acc) {
|
||||
throw $this->createAccessDeniedException();
|
||||
}
|
||||
|
@ -316,50 +378,6 @@ class ApprovalController extends AbstractController
|
|||
}
|
||||
}
|
||||
|
||||
#[Route('/api/approval/check-permission/{docId}', name: 'api_approval_check_permission', methods: ['GET'])]
|
||||
public function checkApprovalPermission(
|
||||
$docId,
|
||||
#[CurrentUser] ?User $user,
|
||||
Access $access,
|
||||
EntityManagerInterface $entityManager
|
||||
): Response {
|
||||
try {
|
||||
$acc = $access->hasRole('settings');
|
||||
if (!$acc) {
|
||||
return $this->json(['canApprove' => false, 'message' => 'دسترسی محدود']);
|
||||
}
|
||||
|
||||
$business = $acc['bid'];
|
||||
$businessSettings = $entityManager->getRepository(Business::class)->find($business->getId());
|
||||
|
||||
$document = $entityManager->getRepository(HesabdariDoc::class)->findOneByIncludePreview([
|
||||
'id' => $docId,
|
||||
'bid' => $business
|
||||
]);
|
||||
|
||||
if (!$document) {
|
||||
return $this->json(['canApprove' => false, 'message' => 'سند یافت نشد']);
|
||||
}
|
||||
|
||||
$canApprove = $this->canUserApproveDocument($user, $businessSettings, $document);
|
||||
|
||||
return $this->json([
|
||||
'canApprove' => $canApprove,
|
||||
'documentStatus' => [
|
||||
'isPreview' => $document->isPreview(),
|
||||
'isApproved' => $document->isApproved(),
|
||||
'approvedBy' => $document->getApprovedBy() ? $document->getApprovedBy()->getFullName() : null
|
||||
]
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->json([
|
||||
'canApprove' => false,
|
||||
'message' => 'خطا در بررسی مجوز: ' . $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
private function canUserApproveDocument(User $user, Business $business, HesabdariDoc $document): bool
|
||||
{
|
||||
if ($user->getEmail() === $business->getOwner()->getEmail()) {
|
||||
|
@ -370,11 +388,9 @@ class ApprovalController extends AbstractController
|
|||
|
||||
switch ($documentType) {
|
||||
case 'invoice':
|
||||
return $business->getInvoiceApprover() === $user->getEmail();
|
||||
return $business->getApproverSellInvoice() === $user->getEmail();
|
||||
case 'warehouse':
|
||||
return $business->getWarehouseApprover() === $user->getEmail();
|
||||
case 'financial':
|
||||
return $business->getFinancialApprover() === $user->getEmail();
|
||||
return $business->getApproverWarehouseTransfer() === $user->getEmail();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -405,7 +421,7 @@ class ApprovalController extends AbstractController
|
|||
return true;
|
||||
}
|
||||
|
||||
return $business->getWarehouseApprover() === $user->getEmail();
|
||||
return $business->getApproverWarehouseTransfer() === $user->getEmail();
|
||||
}
|
||||
|
||||
private function canUserApproveSalesInvoice(User $user, Business $business): bool
|
||||
|
@ -414,15 +430,6 @@ class ApprovalController extends AbstractController
|
|||
return true;
|
||||
}
|
||||
|
||||
return $business->getInvoiceApprover() === $user->getEmail();
|
||||
}
|
||||
|
||||
private function canUserApproveFinancialDocument(User $user, Business $business): bool
|
||||
{
|
||||
if ($user->getEmail() === $business->getOwner()->getEmail()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $business->getFinancialApprover() === $user->getEmail();
|
||||
return $business->getApproverSellInvoice() === $user->getEmail();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,7 +103,21 @@ class BusinessController extends AbstractController
|
|||
]);
|
||||
if (!$perms)
|
||||
throw $this->createAccessDeniedException();
|
||||
return $this->json(Explore::ExploreBusiness($bus));
|
||||
$result = Explore::ExploreBusiness($bus);
|
||||
// Read approval settings from Business entity (only new fields)
|
||||
$result['approvers'] = [
|
||||
'sellInvoice' => $bus->getApproverSellInvoice(),
|
||||
'buyInvoice' => $bus->getApproverBuyInvoice(),
|
||||
'returnBuy' => $bus->getApproverReturnBuy(),
|
||||
'returnSell' => $bus->getApproverReturnSell(),
|
||||
'warehouseTransfer' => $bus->getApproverWarehouseTransfer(),
|
||||
'receiveFromPersons' => $bus->getApproverReceiveFromPersons(),
|
||||
'payToPersons' => $bus->getApproverPayToPersons(),
|
||||
'accountingDocs' => $bus->getApproverAccountingDocs(),
|
||||
'bankTransfers' => $bus->getApproverBankTransfers(),
|
||||
];
|
||||
|
||||
return $this->json($result);
|
||||
}
|
||||
|
||||
#[Route('/api/business/list/count', name: 'api_bussiness_list_count')]
|
||||
|
@ -246,32 +260,26 @@ class BusinessController extends AbstractController
|
|||
$business->setWalletEnable(false);
|
||||
}
|
||||
}
|
||||
if (array_key_exists('requireTwoStepApproval', $params)) {
|
||||
$business->setRequireTwoStepApproval((bool)$params['requireTwoStepApproval']);
|
||||
}
|
||||
|
||||
// Set approvers
|
||||
if (array_key_exists('invoiceApprover', $params)) {
|
||||
$business->setInvoiceApprover($params['invoiceApprover']);
|
||||
}
|
||||
// Approval settings
|
||||
$business->setRequireTwoStepApproval((bool)$params['requireTwoStepApproval'] ?? false);
|
||||
|
||||
if (array_key_exists('warehouseApprover', $params)) {
|
||||
$business->setWarehouseApprover($params['warehouseApprover']);
|
||||
}
|
||||
$approvers = $params['approvers'] ?? [];
|
||||
|
||||
if (array_key_exists('financialApprover', $params)) {
|
||||
$business->setFinancialApprover($params['financialApprover']);
|
||||
}
|
||||
$business->setApproverSellInvoice($approvers['sellInvoice'] ?? null);
|
||||
$business->setApproverBuyInvoice($approvers['buyInvoice'] ?? null);
|
||||
$business->setApproverReturnBuy($approvers['returnBuy'] ?? null);
|
||||
$business->setApproverReturnSell($approvers['returnSell'] ?? null);
|
||||
$business->setApproverWarehouseTransfer($approvers['warehouseTransfer'] ?? null);
|
||||
$business->setApproverReceiveFromPersons($approvers['receiveFromPersons'] ?? null);
|
||||
$business->setApproverPayToPersons($approvers['payToPersons'] ?? null);
|
||||
$business->setApproverAccountingDocs($approvers['accountingDocs'] ?? null);
|
||||
$business->setApproverBankTransfers($approvers['bankTransfers'] ?? null);
|
||||
|
||||
if (array_key_exists('requireWarrantyOnDelivery', $params)) {
|
||||
$business->setRequireWarrantyOnDelivery($params['requireWarrantyOnDelivery']);
|
||||
}
|
||||
if (array_key_exists('activationGraceDays', $params)) {
|
||||
$business->setActivationGraceDays($params['activationGraceDays']);
|
||||
}
|
||||
if (array_key_exists('matchWarrantyToSerial', $params)) {
|
||||
$business->setMatchWarrantyToSerial($params['matchWarrantyToSerial']);
|
||||
}
|
||||
// Warranty settings
|
||||
$business->setRequireWarrantyOnDelivery($params['requireWarrantyOnDelivery'] ?? false);
|
||||
$business->setActivationGraceDays($params['activationGraceDays'] ?? 7);
|
||||
$business->setMatchWarrantyToSerial($params['matchWarrantyToSerial'] ?? false);
|
||||
|
||||
//get Money type
|
||||
if (!array_key_exists('arzmain', $params) && $isNew) {
|
||||
|
@ -287,9 +295,12 @@ class BusinessController extends AbstractController
|
|||
$business->setDateSubmit(time());
|
||||
$entityManager->persist($business);
|
||||
$entityManager->flush();
|
||||
|
||||
// No registry usage; settings persisted on Business entity
|
||||
if ($isNew) {
|
||||
$perms = new Permission();
|
||||
$giftCredit = (int) $registryMGR->get('system_settings', 'gift_credit', 0);
|
||||
$giftCreditRaw = $registryMGR->get('system_settings', 'gift_credit');
|
||||
$giftCredit = (int) ($giftCreditRaw ?? 0);
|
||||
$business->setSmsCharge($giftCredit);
|
||||
$perms->setBid($business);
|
||||
$perms->setUser($this->getUser());
|
||||
|
|
|
@ -316,14 +316,39 @@ class Business
|
|||
#[ORM\Column(nullable: true)]
|
||||
private ?bool $requireTwoStepApproval = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $invoiceApprover = null;
|
||||
// Two-step approval extended configuration
|
||||
#[ORM\Column(nullable: true)]
|
||||
private ?bool $approvalUseSameApprover = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $warehouseApprover = null;
|
||||
private ?string $approverAll = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $financialApprover = null;
|
||||
private ?string $approverSellInvoice = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $approverBuyInvoice = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $approverReturnBuy = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $approverReturnSell = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $approverWarehouseTransfer = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $approverReceiveFromPersons = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $approverPayToPersons = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $approverAccountingDocs = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $approverBankTransfers = null;
|
||||
|
||||
#[ORM\Column(nullable: true)]
|
||||
private ?bool $requireWarrantyOnDelivery = null;
|
||||
|
@ -2231,36 +2256,102 @@ class Business
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getInvoiceApprover(): ?string
|
||||
public function getApproverSellInvoice(): ?string
|
||||
{
|
||||
return $this->invoiceApprover;
|
||||
return $this->approverSellInvoice;
|
||||
}
|
||||
|
||||
public function setInvoiceApprover(?string $invoiceApprover): static
|
||||
public function setApproverSellInvoice(?string $approverSellInvoice): static
|
||||
{
|
||||
$this->invoiceApprover = $invoiceApprover;
|
||||
$this->approverSellInvoice = $approverSellInvoice;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getWarehouseApprover(): ?string
|
||||
public function getApproverBuyInvoice(): ?string
|
||||
{
|
||||
return $this->warehouseApprover;
|
||||
return $this->approverBuyInvoice;
|
||||
}
|
||||
|
||||
public function setWarehouseApprover(?string $warehouseApprover): static
|
||||
public function setApproverBuyInvoice(?string $approverBuyInvoice): static
|
||||
{
|
||||
$this->warehouseApprover = $warehouseApprover;
|
||||
$this->approverBuyInvoice = $approverBuyInvoice;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFinancialApprover(): ?string
|
||||
public function getApproverReturnBuy(): ?string
|
||||
{
|
||||
return $this->financialApprover;
|
||||
return $this->approverReturnBuy;
|
||||
}
|
||||
|
||||
public function setFinancialApprover(?string $financialApprover): static
|
||||
public function setApproverReturnBuy(?string $approverReturnBuy): static
|
||||
{
|
||||
$this->financialApprover = $financialApprover;
|
||||
$this->approverReturnBuy = $approverReturnBuy;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getApproverReturnSell(): ?string
|
||||
{
|
||||
return $this->approverReturnSell;
|
||||
}
|
||||
|
||||
public function setApproverReturnSell(?string $approverReturnSell): static
|
||||
{
|
||||
$this->approverReturnSell = $approverReturnSell;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getApproverWarehouseTransfer(): ?string
|
||||
{
|
||||
return $this->approverWarehouseTransfer;
|
||||
}
|
||||
|
||||
public function setApproverWarehouseTransfer(?string $approverWarehouseTransfer): static
|
||||
{
|
||||
$this->approverWarehouseTransfer = $approverWarehouseTransfer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getApproverReceiveFromPersons(): ?string
|
||||
{
|
||||
return $this->approverReceiveFromPersons;
|
||||
}
|
||||
|
||||
public function setApproverReceiveFromPersons(?string $approverReceiveFromPersons): static
|
||||
{
|
||||
$this->approverReceiveFromPersons = $approverReceiveFromPersons;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getApproverPayToPersons(): ?string
|
||||
{
|
||||
return $this->approverPayToPersons;
|
||||
}
|
||||
|
||||
public function setApproverPayToPersons(?string $approverPayToPersons): static
|
||||
{
|
||||
$this->approverPayToPersons = $approverPayToPersons;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getApproverAccountingDocs(): ?string
|
||||
{
|
||||
return $this->approverAccountingDocs;
|
||||
}
|
||||
|
||||
public function setApproverAccountingDocs(?string $approverAccountingDocs): static
|
||||
{
|
||||
$this->approverAccountingDocs = $approverAccountingDocs;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getApproverBankTransfers(): ?string
|
||||
{
|
||||
return $this->approverBankTransfers;
|
||||
}
|
||||
|
||||
public function setApproverBankTransfers(?string $approverBankTransfers): static
|
||||
{
|
||||
$this->approverBankTransfers = $approverBankTransfers;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
|
@ -579,9 +579,17 @@ class Explore
|
|||
'walletEnabled' => $item->isWalletEnable(),
|
||||
'walletMatchBank' => $item->getWalletMatchBank() ? $item->getWalletMatchBank()->getId() : null,
|
||||
'requireTwoStepApproval' => $item->isRequireTwoStepApproval(),
|
||||
'invoiceApprover' => $item->getInvoiceApprover(),
|
||||
'warehouseApprover' => $item->getWarehouseApprover(),
|
||||
'financialApprover' => $item->getFinancialApprover(),
|
||||
'approvers' => [
|
||||
'sellInvoice' => $item->getApproverSellInvoice(),
|
||||
'buyInvoice' => $item->getApproverBuyInvoice(),
|
||||
'returnBuy' => $item->getApproverReturnBuy(),
|
||||
'returnSell' => $item->getApproverReturnSell(),
|
||||
'warehouseTransfer' => $item->getApproverWarehouseTransfer(),
|
||||
'receiveFromPersons' => $item->getApproverReceiveFromPersons(),
|
||||
'payToPersons' => $item->getApproverPayToPersons(),
|
||||
'accountingDocs' => $item->getApproverAccountingDocs(),
|
||||
'bankTransfers' => $item->getApproverBankTransfers(),
|
||||
],
|
||||
'updateSellPrice' => $item->isCommodityUpdateSellPriceAuto(),
|
||||
'updateBuyPrice' => $item->isCommodityUpdateBuyPriceAuto(),
|
||||
'requireWarrantyOnDelivery' => $item->getRequireWarrantyOnDelivery(),
|
||||
|
|
|
@ -82,6 +82,7 @@
|
|||
v-model="item.warrantyStartDate"
|
||||
label="شروع گارانتی"
|
||||
:rules="[rules.date]"
|
||||
:ignore-year-range="true"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
|
@ -89,6 +90,7 @@
|
|||
v-model="item.warrantyEndDate"
|
||||
label="پایان گارانتی"
|
||||
:rules="[rules.date, (value: any) => rules.endDate(value, item.warrantyStartDate)]"
|
||||
:ignore-year-range="true"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
|
|
|
@ -33,13 +33,13 @@
|
|||
</v-col>
|
||||
|
||||
<v-col cols="12" md="6">
|
||||
<h-date-picker v-model="formData.warrantyStartDate" label="تاریخ شروع گارانتی" :rules="[rules.date]" dense
|
||||
<h-date-picker v-model="formData.warrantyStartDate" label="تاریخ شروع گارانتی" :rules="[rules.date]" :ignore-year-range="true" dense
|
||||
outlined hide-details="auto" />
|
||||
</v-col>
|
||||
|
||||
<v-col cols="12" md="6">
|
||||
<h-date-picker v-model="formData.warrantyEndDate" label="تاریخ پایان گارانتی"
|
||||
:rules="[(v: any) => rules.endDate(v, formData.warrantyStartDate)]" dense outlined
|
||||
:rules="[(v: any) => rules.endDate(v, formData.warrantyStartDate)]" :ignore-year-range="true" dense outlined
|
||||
hide-details="auto" />
|
||||
</v-col>
|
||||
|
||||
|
|
|
@ -24,11 +24,9 @@ export function canApproveDocument(businessSettings, currentUserEmail, isBusines
|
|||
// Check specific approver based on document type
|
||||
switch (documentType) {
|
||||
case 'invoice':
|
||||
return businessSettings.invoiceApprover === currentUserEmail;
|
||||
return businessSettings.approvers.sellInvoice === currentUserEmail;
|
||||
case 'warehouse':
|
||||
return businessSettings.warehouseApprover === currentUserEmail;
|
||||
case 'financial':
|
||||
return businessSettings.financialApprover === currentUserEmail;
|
||||
return businessSettings.approvers.warehouseTransfer === currentUserEmail;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -35,13 +35,13 @@
|
|||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
<v-tooltip text="تایید پرداختهای انتخابی" location="bottom">
|
||||
<!-- <v-tooltip text="تایید پرداختهای انتخابی" location="bottom">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn v-bind="props" icon color="success" @click="approveSelectedPayments">
|
||||
<v-icon>mdi-check-decagram</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
</v-tooltip> -->
|
||||
<v-menu>
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn v-bind="props" icon color="success">
|
||||
|
@ -441,27 +441,27 @@ const updateSelectedSum = () => {
|
|||
}
|
||||
};
|
||||
|
||||
const approveSelectedPayments = async () => {
|
||||
if (selectedItems.value.length === 0) {
|
||||
Swal.fire({ text: 'هیچ آیتمی انتخاب نشده است.', icon: 'warning', confirmButtonText: 'قبول' });
|
||||
return;
|
||||
}
|
||||
const res = await Swal.fire({ title: 'تایید پرداختها', text: 'پرداختهای انتخابی تایید خواهند شد.', icon: 'question', showCancelButton: true, confirmButtonText: 'بله', cancelButtonText: 'خیر' });
|
||||
if (!res.isConfirmed) return;
|
||||
loading.value = true;
|
||||
try {
|
||||
for (const it of selectedItems.value) {
|
||||
await axios.post(`/api/sell/payment/approve/${it.code}`);
|
||||
}
|
||||
Swal.fire({ text: 'پرداختها تایید شدند.', icon: 'success', confirmButtonText: 'قبول' });
|
||||
selectedItems.value = [];
|
||||
await loadData();
|
||||
} catch (e) {
|
||||
Swal.fire({ text: 'خطا در تایید پرداختها', icon: 'error', confirmButtonText: 'قبول' });
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
// const approveSelectedPayments = async () => {
|
||||
// if (selectedItems.value.length === 0) {
|
||||
// Swal.fire({ text: 'هیچ آیتمی انتخاب نشده است.', icon: 'warning', confirmButtonText: 'قبول' });
|
||||
// return;
|
||||
// }
|
||||
// const res = await Swal.fire({ title: 'تایید پرداختها', text: 'پرداختهای انتخابی تایید خواهند شد.', icon: 'question', showCancelButton: true, confirmButtonText: 'بله', cancelButtonText: 'خیر' });
|
||||
// if (!res.isConfirmed) return;
|
||||
// loading.value = true;
|
||||
// try {
|
||||
// for (const it of selectedItems.value) {
|
||||
// await axios.post(`/api/sell/payment/approve/${it.code}`);
|
||||
// }
|
||||
// Swal.fire({ text: 'پرداختها تایید شدند.', icon: 'success', confirmButtonText: 'قبول' });
|
||||
// selectedItems.value = [];
|
||||
// await loadData();
|
||||
// } catch (e) {
|
||||
// Swal.fire({ text: 'خطا در تایید پرداختها', icon: 'error', confirmButtonText: 'قبول' });
|
||||
// } finally {
|
||||
// loading.value = false;
|
||||
// }
|
||||
// };
|
||||
|
||||
const print = async (allItems = true) => {
|
||||
if (!allItems && selectedItems.value.length === 0) {
|
||||
|
|
|
@ -34,9 +34,9 @@
|
|||
</v-btn>
|
||||
</template>
|
||||
<v-list>
|
||||
<v-list-subheader color="primary" v-if="business.requireTwoStepApproval">وضعیت تایید</v-list-subheader>
|
||||
<v-list-subheader color="primary" v-if="checkApprover()">وضعیت تایید</v-list-subheader>
|
||||
<v-list-item class="text-dark" title="تایید فاکتورهای انتخابی" @click="approveSelectedInvoices"
|
||||
v-if="business.requireTwoStepApproval">
|
||||
v-if="checkApprover()">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="green" icon="mdi-check-decagram"></v-icon>
|
||||
</template>
|
||||
|
@ -404,7 +404,7 @@ export default defineComponent({
|
|||
invoiceIndex: true
|
||||
},
|
||||
plugins: {},
|
||||
business: { requireTwoStepApproval: false, invoiceApprover: null },
|
||||
business: { requireTwoStepApproval: false, approvers: { sellInvoice: null } },
|
||||
currentUser: { email: '', owner: false },
|
||||
sumSelected: 0,
|
||||
sumSelectedProfit: 0,
|
||||
|
@ -507,6 +507,9 @@ export default defineComponent({
|
|||
isPluginActive(pluginCode) {
|
||||
return this.plugins && this.plugins[pluginCode] !== undefined;
|
||||
},
|
||||
checkApprover() {
|
||||
return this.business.requireTwoStepApproval && (this.business.approvers.sellInvoice == this.currentUser.email || this.currentUser.owner === true);
|
||||
},
|
||||
async loadPlugins() {
|
||||
try {
|
||||
const response = await axios.post('/api/plugin/get/actives');
|
||||
|
@ -519,10 +522,10 @@ export default defineComponent({
|
|||
async loadBusinessInfo() {
|
||||
try {
|
||||
const response = await axios.get('/api/business/get/info/' + localStorage.getItem('activeBid'));
|
||||
this.business = response.data || { requireTwoStepApproval: false, invoiceApprover: null };
|
||||
this.business = response.data || { requireTwoStepApproval: false, approvers: { sellInvoice: null } };
|
||||
} catch (error) {
|
||||
console.error('Error loading business info:', error);
|
||||
this.business = { requireTwoStepApproval: false, invoiceApprover: null };
|
||||
this.business = { requireTwoStepApproval: false, approvers: { sellInvoice: null } };
|
||||
}
|
||||
},
|
||||
async loadCurrentUser() {
|
||||
|
@ -639,11 +642,11 @@ export default defineComponent({
|
|||
return 'success';
|
||||
},
|
||||
canShowApprovalButton(item) {
|
||||
if (!this.business?.requireTwoStepApproval) return false;
|
||||
if (!this.checkApprover()) return false;
|
||||
|
||||
if (item?.isApproved || (!item?.isPreview && !item?.isApproved)) return false;
|
||||
if (item?.isApproved) return false;
|
||||
|
||||
return this.business?.invoiceApprover === this.currentUser?.email || this.currentUser?.owner === true;
|
||||
return true;
|
||||
},
|
||||
async approveInvoice(code) {
|
||||
try {
|
||||
|
@ -660,7 +663,7 @@ export default defineComponent({
|
|||
}
|
||||
},
|
||||
canShowUnapproveButton(item) {
|
||||
return !this.canShowApprovalButton(item);
|
||||
return !this.canShowApprovalButton(item) && this.checkApprover();
|
||||
},
|
||||
async unapproveInvoice(code) {
|
||||
try {
|
||||
|
|
|
@ -24,10 +24,13 @@
|
|||
<v-tab value="2">
|
||||
{{ $t('dialog.global_settings') }}
|
||||
</v-tab>
|
||||
<v-tab value="3" v-if="isPluginActive('warranty')">
|
||||
<v-tab value="3" v-if="isPluginActive('accpro')">
|
||||
تایید اسناد
|
||||
</v-tab>
|
||||
<v-tab value="4" v-if="isPluginActive('warranty')">
|
||||
{{ $t('dialog.warranty_settings') }}
|
||||
</v-tab>
|
||||
<v-tab value="4" v-if="showBackupTab">
|
||||
<v-tab value="5" v-if="showBackupTab">
|
||||
نسخه پشتیبان
|
||||
</v-tab>
|
||||
</v-tabs>
|
||||
|
@ -198,7 +201,170 @@
|
|||
</v-card-text>
|
||||
</v-card>
|
||||
</v-tabs-window-item>
|
||||
<v-tabs-window-item value="3" v-if="isPluginActive('warranty')">
|
||||
|
||||
<v-tabs-window-item value="3" v-if="isPluginActive('accpro')">
|
||||
<v-card>
|
||||
<v-card-text>
|
||||
<h3 class="text-primary mb-6">تایید اسناد</h3>
|
||||
<v-row>
|
||||
<v-col cols="12" md="8">
|
||||
<v-card variant="outlined" class="mb-6">
|
||||
<v-card-text>
|
||||
<v-switch
|
||||
v-model="content.requireTwoStepApproval"
|
||||
label="فعالسازی تایید دومرحلهای برای اسناد"
|
||||
color="primary"
|
||||
hide-details
|
||||
class="mb-2"
|
||||
></v-switch>
|
||||
<div class="text-body-2 text-medium-emphasis mb-2">
|
||||
با فعالسازی این گزینه، تمام اسناد انتخابی نیاز به تایید خواهند داشت.
|
||||
</div>
|
||||
|
||||
<v-expand-transition>
|
||||
<div v-if="content.requireTwoStepApproval">
|
||||
<v-divider class="my-4"></v-divider>
|
||||
<h4 class="text-subtitle-1 mb-3">تعیین تاییدکنندگان</h4>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" md="6">
|
||||
<v-select
|
||||
v-model="content.approvers.sellInvoice"
|
||||
:items="users"
|
||||
item-title="name"
|
||||
item-value="email"
|
||||
label="تاییدکننده فاکتور فروش"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
clearable
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<v-select
|
||||
v-model="content.approvers.buyInvoice"
|
||||
:items="users"
|
||||
item-title="name"
|
||||
item-value="email"
|
||||
label="تاییدکننده فاکتور خرید"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
clearable
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<v-select
|
||||
v-model="content.approvers.returnBuy"
|
||||
:items="users"
|
||||
item-title="name"
|
||||
item-value="email"
|
||||
label="تاییدکننده برگشت از خرید"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
clearable
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<v-select
|
||||
v-model="content.approvers.returnSell"
|
||||
:items="users"
|
||||
item-title="name"
|
||||
item-value="email"
|
||||
label="تاییدکننده برگشت از فروش"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
clearable
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<v-select
|
||||
v-model="content.approvers.warehouseTransfer"
|
||||
:items="users"
|
||||
item-title="name"
|
||||
item-value="email"
|
||||
label="تاییدکننده حواله انبار"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
clearable
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<v-select
|
||||
v-model="content.approvers.receiveFromPersons"
|
||||
:items="users"
|
||||
item-title="name"
|
||||
item-value="email"
|
||||
label="تاییدکننده دریافت از اشخاص"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
clearable
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<v-select
|
||||
v-model="content.approvers.payToPersons"
|
||||
:items="users"
|
||||
item-title="name"
|
||||
item-value="email"
|
||||
label="تاییدکننده پرداخت به اشخاص"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
clearable
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<v-select
|
||||
v-model="content.approvers.accountingDocs"
|
||||
:items="users"
|
||||
item-title="name"
|
||||
item-value="email"
|
||||
label="تاییدکننده اسناد حسابداری"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
clearable
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<v-select
|
||||
v-model="content.approvers.bankTransfers"
|
||||
:items="users"
|
||||
item-title="name"
|
||||
item-value="email"
|
||||
label="تاییدکننده انتقالها (بانکداری)"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
clearable
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<div class="text-caption text-medium-emphasis mt-4">
|
||||
<v-icon size="small" color="info" class="me-1">mdi-information</v-icon>
|
||||
در صورت عدم انتخاب تاییدکننده برای هر بخش، فقط مدیر کسب و کار مجاز به تایید است.
|
||||
</div>
|
||||
</div>
|
||||
</v-expand-transition>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
<v-col cols="12" md="4">
|
||||
<v-card variant="outlined">
|
||||
<v-card-title class="text-h6 text-primary">
|
||||
<v-icon icon="mdi-information-outline" class="mr-2"></v-icon>
|
||||
نکات
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-list density="compact">
|
||||
<v-list-item title="صاحب کسبوکار همیشه مجاز به تایید همه اسناد است." />
|
||||
<v-list-item title="میتوانید یک تاییدکننده برای همه یا تاییدکنندههای مجزا تعیین کنید." />
|
||||
</v-list>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-tabs-window-item>
|
||||
<v-tabs-window-item value="4" v-if="isPluginActive('warranty')">
|
||||
<v-card>
|
||||
<v-card-text>
|
||||
<h3 class="text-primary mb-6">تنظیمات گارانتی</h3>
|
||||
|
@ -370,126 +536,7 @@
|
|||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
<!-- تایید دومرحلهای -->
|
||||
<v-card v-if="isPluginActive('accpro')" variant="outlined" class="mb-6">
|
||||
<v-card-title class="text-h6 text-primary">
|
||||
<v-icon icon="mdi-shield-check" class="mr-2"></v-icon>
|
||||
تایید دومرحلهای
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-switch
|
||||
v-model="content.requireTwoStepApproval"
|
||||
label="فعالسازی تایید دومرحلهای برای اسناد"
|
||||
color="primary"
|
||||
hide-details
|
||||
class="mb-2"
|
||||
></v-switch>
|
||||
<div class="text-body-2 text-medium-emphasis mb-2">
|
||||
با فعالسازی این گزینه، تمام فاکتورها، حوالههای انبار، دریافتها و پرداختها نیاز به تایید مدیر خواهند داشت.
|
||||
</div>
|
||||
|
||||
<v-expand-transition>
|
||||
<div v-if="content.requireTwoStepApproval">
|
||||
<v-divider class="my-4"></v-divider>
|
||||
<h4 class="text-subtitle-1 mb-3">تعیین تاییدکنندگان</h4>
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
<v-select
|
||||
v-model="content.invoiceApprover"
|
||||
:items="users"
|
||||
item-title="name"
|
||||
item-value="email"
|
||||
label="تاییدکننده فاکتور فروش"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
clearable
|
||||
hint="کاربری که میتواند فاکتورهای فروش را تایید کند"
|
||||
persistent-hint
|
||||
>
|
||||
<template v-slot:item="{ item, props }">
|
||||
<v-list-item v-bind="props">
|
||||
<template v-slot:prepend>
|
||||
<v-icon
|
||||
:color="item.owner ? 'success' : 'primary'"
|
||||
size="small"
|
||||
>
|
||||
{{ item.owner ? 'mdi-crown' : 'mdi-account' }}
|
||||
</v-icon>
|
||||
</template>
|
||||
<v-list-item-title>{{ item.name }}</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ item.email }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
</template>
|
||||
</v-select>
|
||||
<div class="text-caption text-medium-emphasis mt-1">
|
||||
این کاربر افزون بر مدیر کسب و کار میتواند فاکتورهای فروش را تایید کند
|
||||
</div>
|
||||
</v-col>
|
||||
|
||||
<v-col cols="12">
|
||||
<v-select
|
||||
v-model="content.warehouseApprover"
|
||||
:items="users"
|
||||
item-title="name"
|
||||
item-value="email"
|
||||
label="تاییدکننده حواله انبار"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
clearable
|
||||
hint="کاربری که میتواند حوالههای انبار را تایید کند"
|
||||
persistent-hint
|
||||
>
|
||||
<template v-slot:item="{ item, props }">
|
||||
<v-list-item v-bind="props">
|
||||
<template v-slot:prepend>
|
||||
<v-icon
|
||||
:color="item.owner ? 'success' : 'primary'"
|
||||
size="small"
|
||||
>
|
||||
{{ item.owner ? 'mdi-crown' : 'mdi-account' }}
|
||||
</v-icon>
|
||||
</template>
|
||||
<v-list-item-title>{{ item.name }}</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ item.email }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
</template>
|
||||
</v-select>
|
||||
<div class="text-caption text-medium-emphasis mt-1">
|
||||
این کاربر افزون بر مدیر کسب و کار میتواند حوالههای انبار را تایید کند
|
||||
</div>
|
||||
</v-col>
|
||||
|
||||
<!-- تاییدکننده دریافت و پرداخت مالی (غیرفعال فعلاً) -->
|
||||
<!--
|
||||
<v-col cols="12">
|
||||
<v-select
|
||||
v-model="content.financialApprover"
|
||||
:items="users"
|
||||
item-title="name"
|
||||
item-value="email"
|
||||
label="تاییدکننده دریافت و پرداخت مالی"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
clearable
|
||||
hint="کاربری که میتواند دریافتها و پرداختها را تایید کند"
|
||||
persistent-hint
|
||||
/>
|
||||
</v-col>
|
||||
-->
|
||||
</v-row>
|
||||
|
||||
<div class="text-caption text-medium-emphasis">
|
||||
<v-icon size="small" color="info" class="me-1">mdi-information</v-icon>
|
||||
در صورت عدم انتخاب تاییدکننده، فقط مدیر کسب و کار میتواند اسناد را تایید کند
|
||||
</div>
|
||||
<div class="text-caption text-medium-emphasis mt-2">
|
||||
<v-icon size="small" color="success" class="me-1">mdi-check-circle</v-icon>
|
||||
<strong>نکته:</strong> صاحب کسب و کار همیشه میتواند تمام اسناد را تأیید کند و نیازی به تعیین مجدد ندارد
|
||||
</div>
|
||||
</div>
|
||||
</v-expand-transition>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
|
||||
<v-card variant="outlined">
|
||||
<v-card-title class="text-h6 text-primary">
|
||||
|
@ -594,7 +641,7 @@
|
|||
</v-card-text>
|
||||
</v-card>
|
||||
</v-tabs-window-item>
|
||||
<v-tabs-window-item value="4" v-if="showBackupTab">
|
||||
<v-tabs-window-item value="5" v-if="showBackupTab">
|
||||
<v-card>
|
||||
<v-card-text>
|
||||
<h3 class="text-primary mb-4">نسخه پشتیبان از اطلاعات کسب و کار</h3>
|
||||
|
@ -743,9 +790,17 @@ export default {
|
|||
walletEnabled: false,
|
||||
walletMatchBank: null,
|
||||
requireTwoStepApproval: false,
|
||||
invoiceApprover: null,
|
||||
warehouseApprover: null,
|
||||
financialApprover: null,
|
||||
approvers: {
|
||||
sellInvoice: null,
|
||||
buyInvoice: null,
|
||||
returnBuy: null,
|
||||
returnSell: null,
|
||||
warehouseTransfer: null,
|
||||
receiveFromPersons: null,
|
||||
payToPersons: null,
|
||||
accountingDocs: null,
|
||||
bankTransfers: null
|
||||
},
|
||||
year: {
|
||||
startShamsi: '',
|
||||
endShamsi: '',
|
||||
|
@ -871,9 +926,7 @@ export default {
|
|||
'walletEnabled': this.content.walletEnabled,
|
||||
'walletMatchBank': this.content.walletMatchBank,
|
||||
'requireTwoStepApproval': this.content.requireTwoStepApproval,
|
||||
'invoiceApprover': this.content.invoiceApprover,
|
||||
'warehouseApprover': this.content.warehouseApprover,
|
||||
'financialApprover': this.content.financialApprover,
|
||||
'approvers': this.content.approvers,
|
||||
'year': this.content.year,
|
||||
'commodityUpdateBuyPriceAuto': this.content.updateBuyPrice,
|
||||
'commodityUpdateSellPriceAuto': this.content.updateSellPrice,
|
||||
|
@ -924,19 +977,11 @@ export default {
|
|||
this.content.walletMatchBank = this.content.walletMatchBank.id;
|
||||
}
|
||||
|
||||
// اطمینان از وجود فیلدهای تأییدکننده
|
||||
if (!this.content.hasOwnProperty('invoiceApprover')) {
|
||||
this.content.invoiceApprover = null;
|
||||
}
|
||||
if (!this.content.hasOwnProperty('warehouseApprover')) {
|
||||
this.content.warehouseApprover = null;
|
||||
}
|
||||
if (!this.content.hasOwnProperty('financialApprover')) {
|
||||
this.content.financialApprover = null;
|
||||
}
|
||||
if (!this.content.hasOwnProperty('requireTwoStepApproval')) {
|
||||
this.content.requireTwoStepApproval = false;
|
||||
}
|
||||
// اطمینان از وجود فیلدهای تایید اسناد
|
||||
if (!this.content.hasOwnProperty('requireTwoStepApproval')) this.content.requireTwoStepApproval = false;
|
||||
if (!this.content.hasOwnProperty('approvers')) this.content.approvers = {};
|
||||
const approverKeys = ['sellInvoice','buyInvoice','returnBuy','returnSell','warehouseTransfer','receiveFromPersons','payToPersons','accountingDocs','bankTransfers'];
|
||||
approverKeys.forEach(k => { if (!this.content.approvers.hasOwnProperty(k)) this.content.approvers[k] = null; });
|
||||
|
||||
// سپس سایر دادهها را بارگذاری کن
|
||||
const [moneyResponse, banksResponse, usersResponse, pluginsResponse] = await Promise.all([
|
||||
|
|
|
@ -81,6 +81,12 @@
|
|||
</template>
|
||||
<v-list-item-title>تایید حواله</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item v-if="canShowUnapproveButton(item)" @click="unapproveTicket(item.code)">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="red">mdi-cancel</v-icon>
|
||||
</template>
|
||||
<v-list-item-title>لغو تایید حواله</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item @click="deleteTicket('output', item.code)">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="error">mdi-delete</v-icon>
|
||||
|
@ -140,6 +146,12 @@
|
|||
</template>
|
||||
<v-list-item-title>تایید حواله</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item v-if="canShowUnapproveButton(item)" @click="unapproveTicket(item.code)">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="red">mdi-cancel</v-icon>
|
||||
</template>
|
||||
<v-list-item-title>لغو تایید حواله</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item @click="deleteTicket('input', item.code)">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="error">mdi-delete</v-icon>
|
||||
|
@ -199,6 +211,12 @@
|
|||
</template>
|
||||
<v-list-item-title>تایید حواله</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item v-if="canShowUnapproveButton(item)" @click="unapproveTicket(item.code)">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="red">mdi-cancel</v-icon>
|
||||
</template>
|
||||
<v-list-item-title>لغو تایید حواله</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item @click="deleteTicket('transfer', item.code)">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="error">mdi-delete</v-icon>
|
||||
|
@ -258,6 +276,12 @@
|
|||
</template>
|
||||
<v-list-item-title>تایید حواله</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item v-if="canShowUnapproveButton(item)" @click="unapproveTicket(item.code)">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="red">mdi-cancel</v-icon>
|
||||
</template>
|
||||
<v-list-item-title>لغو تایید حواله</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item @click="deleteTicket('waste', item.code)">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="error">mdi-delete</v-icon>
|
||||
|
@ -381,7 +405,7 @@ const wasteSubTab = ref<'approved' | 'pending'>('approved');
|
|||
const showColumnDialog = ref(false);
|
||||
const business = ref({
|
||||
requireTwoStepApproval: false,
|
||||
warehouseApprover: null
|
||||
approvers: { warehouseTransfer: null }
|
||||
});
|
||||
const currentUser = ref({ email: '', owner: false });
|
||||
|
||||
|
@ -483,10 +507,10 @@ const displayWasteItems = computed(() => {
|
|||
const loadBusinessInfo = async () => {
|
||||
try {
|
||||
const response = await axios.get('/api/business/get/info/' + localStorage.getItem('activeBid'));
|
||||
business.value = response.data || { requireTwoStepApproval: false, warehouseApprover: null };
|
||||
business.value = response.data || { requireTwoStepApproval: false, approvers: { warehouseTransfer: null } };
|
||||
} catch (error: any) {
|
||||
console.error('Error loading business info:', error);
|
||||
business.value = { requireTwoStepApproval: false, warehouseApprover: null };
|
||||
business.value = { requireTwoStepApproval: false, approvers: { warehouseTransfer: null } };
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -525,12 +549,18 @@ const loadData = async () => {
|
|||
}
|
||||
};
|
||||
|
||||
const checkApprover = () => {
|
||||
return business.value.requireTwoStepApproval && (business.value.approvers.warehouseTransfer === currentUser.value.email || currentUser.value.owner === true);
|
||||
};
|
||||
|
||||
const canShowApprovalButton = (item: Ticket) => {
|
||||
if (!business.value.requireTwoStepApproval) return false;
|
||||
|
||||
if (!checkApprover()) return false;
|
||||
if (item?.approved) return false;
|
||||
|
||||
return business.value.warehouseApprover === currentUser.value.email || currentUser.value.owner === true;
|
||||
return true;
|
||||
};
|
||||
|
||||
const canShowUnapproveButton = (item: Ticket) => {
|
||||
return !canShowApprovalButton(item) && checkApprover();
|
||||
};
|
||||
|
||||
const approveTicket = async (code: string) => {
|
||||
|
@ -548,6 +578,21 @@ const approveTicket = async (code: string) => {
|
|||
}
|
||||
};
|
||||
|
||||
const unapproveTicket = async (code: string) => {
|
||||
try {
|
||||
loading.value = true;
|
||||
await axios.post(`/api/approval/unapprove/storeroom/${code}`);
|
||||
|
||||
await loadData();
|
||||
|
||||
snackbar.value = { show: true, message: 'حواله لغو تایید شد', color: 'success' };
|
||||
} catch (error: any) {
|
||||
snackbar.value = { show: true, message: 'خطا در لغو تایید حواله: ' + (error.response?.data?.message || error.message), color: 'error' };
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const getApprovalStatusText = (item: Ticket) => {
|
||||
if (!business.value.requireTwoStepApproval) return 'تایید دو مرحلهای غیرفعال';
|
||||
|
||||
|
|
|
@ -1290,31 +1290,31 @@ export default {
|
|||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.input-section >>> .v-field__field {
|
||||
.input-section :deep(.v-field__field) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.custom-input >>> .v-input__control {
|
||||
.custom-input :deep(.v-input__control) {
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
.custom-input >>> .v-text-field__details {
|
||||
.custom-input :deep(.v-text-field__details) {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.custom-input >>> .v-input__slot {
|
||||
.custom-input :deep(.v-input__slot) {
|
||||
border-radius: 12px !important;
|
||||
background: #f8fafc;
|
||||
border: 2px solid #e2e8f0 !important;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.custom-input >>> .v-input__slot:hover {
|
||||
.custom-input :deep(.v-input__slot:hover) {
|
||||
border-color: #3b82f6 !important;
|
||||
}
|
||||
|
||||
.custom-input >>> .v-text-field--focused .v-input__slot {
|
||||
.custom-input :deep(.v-text-field--focused .v-input__slot) {
|
||||
border-color: #3b82f6 !important;
|
||||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||||
}
|
||||
|
@ -1342,7 +1342,7 @@ export default {
|
|||
transition: all 0.3s ease !important;
|
||||
}
|
||||
|
||||
.primary-btn >>> .v-btn__content {
|
||||
.primary-btn :deep(.v-btn__content) {
|
||||
gap: 8px !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
|
@ -1459,7 +1459,7 @@ export default {
|
|||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.custom-input >>> .v-input__control {
|
||||
.custom-input :deep(.v-input__control) {
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
|
@ -1833,7 +1833,7 @@ export default {
|
|||
min-height: 40px !important;
|
||||
}
|
||||
|
||||
.footer-link-btn >>> .v-btn__content {
|
||||
.footer-link-btn :deep(.v-btn__content) {
|
||||
gap: 8px !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
|
@ -2210,7 +2210,7 @@ export default {
|
|||
transition: all 0.3s ease !important;
|
||||
}
|
||||
|
||||
.back-btn >>> .v-btn__content {
|
||||
.back-btn :deep(.v-btn__content) {
|
||||
gap: 8px !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
|
@ -2234,7 +2234,7 @@ export default {
|
|||
transition: all 0.3s ease !important;
|
||||
}
|
||||
|
||||
.success-btn >>> .v-btn__content {
|
||||
.success-btn :deep(.v-btn__content) {
|
||||
gap: 8px !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
|
@ -2256,7 +2256,7 @@ export default {
|
|||
transition: all 0.3s ease !important;
|
||||
}
|
||||
|
||||
.error-btn >>> .v-btn__content {
|
||||
.error-btn :deep(.v-btn__content) {
|
||||
gap: 8px !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
|
|
Loading…
Reference in a new issue