some bug fixes
This commit is contained in:
parent
a579a020bc
commit
9074059abd
|
|
@ -244,6 +244,7 @@ class BackupController extends AbstractController
|
||||||
'قیمت خرید',
|
'قیمت خرید',
|
||||||
'قیمت فروش',
|
'قیمت فروش',
|
||||||
'موجودی',
|
'موجودی',
|
||||||
|
'ارزش اسمی',
|
||||||
'حداقل سفارش',
|
'حداقل سفارش',
|
||||||
'توضیحات',
|
'توضیحات',
|
||||||
'تاریخ ثبت'
|
'تاریخ ثبت'
|
||||||
|
|
@ -258,8 +259,37 @@ class BackupController extends AbstractController
|
||||||
// دریافت کالاها
|
// دریافت کالاها
|
||||||
$commodities = $entityManager->getRepository(\App\Entity\Commodity::class)->findBy(['bid' => $business]);
|
$commodities = $entityManager->getRepository(\App\Entity\Commodity::class)->findBy(['bid' => $business]);
|
||||||
|
|
||||||
|
// محاسبه تجمیعی موجودی کالا بر اساس ردیفهای حسابداری تاییدشده
|
||||||
|
$qb = $entityManager->createQueryBuilder();
|
||||||
|
$qb->select('c.id AS cid, SUM(CASE WHEN d.type IN (:plusTypes) THEN COALESCE(r.commdityCount, 0) WHEN d.type IN (:minusTypes) THEN -COALESCE(r.commdityCount, 0) ELSE 0 END) AS stock')
|
||||||
|
->from(\App\Entity\HesabdariRow::class, 'r')
|
||||||
|
->join('r.doc', 'd')
|
||||||
|
->join('r.commodity', 'c')
|
||||||
|
->where('r.bid = :bid')
|
||||||
|
->andWhere('d.isApproved = :approved')
|
||||||
|
->groupBy('c.id')
|
||||||
|
->setParameter('bid', $business)
|
||||||
|
->setParameter('approved', true)
|
||||||
|
->setParameter('plusTypes', ['buy', 'open_balance', 'rfsell'])
|
||||||
|
->setParameter('minusTypes', ['sell', 'rfbuy']);
|
||||||
|
|
||||||
|
$stockResults = $qb->getQuery()->getArrayResult();
|
||||||
|
$stockMap = [];
|
||||||
|
foreach ($stockResults as $sr) {
|
||||||
|
$stockMap[(int)$sr['cid']] = (float)$sr['stock'];
|
||||||
|
}
|
||||||
|
|
||||||
$row = 2;
|
$row = 2;
|
||||||
foreach ($commodities as $commodity) {
|
foreach ($commodities as $commodity) {
|
||||||
|
// محاسبه موجودی و ارزش اسمی
|
||||||
|
$count = 0.0;
|
||||||
|
if (!$commodity->isKhadamat()) {
|
||||||
|
$count = $stockMap[$commodity->getId()] ?? 0.0;
|
||||||
|
}
|
||||||
|
$priceSell = $commodity->getPriceSell();
|
||||||
|
$priceSell = is_numeric($priceSell) ? (float)$priceSell : 0.0;
|
||||||
|
$nominalValue = $count * $priceSell;
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
$commodity->getName(),
|
$commodity->getName(),
|
||||||
$commodity->getCode(),
|
$commodity->getCode(),
|
||||||
|
|
@ -267,7 +297,8 @@ class BackupController extends AbstractController
|
||||||
$commodity->getUnit() ? $commodity->getUnit()->getName() : '',
|
$commodity->getUnit() ? $commodity->getUnit()->getName() : '',
|
||||||
$commodity->getPriceBuy(),
|
$commodity->getPriceBuy(),
|
||||||
$commodity->getPriceSell(),
|
$commodity->getPriceSell(),
|
||||||
'', // Entity Commodity فیلد موجودی ندارد
|
$count,
|
||||||
|
$nominalValue,
|
||||||
$commodity->getMinOrderCount(), // حداقل سفارش
|
$commodity->getMinOrderCount(), // حداقل سفارش
|
||||||
$commodity->getDes(),
|
$commodity->getDes(),
|
||||||
'' // Entity Commodity فیلد تاریخ ثبت ندارد
|
'' // Entity Commodity فیلد تاریخ ثبت ندارد
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@ use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||||
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||||
|
|
||||||
class StoreroomController extends AbstractController
|
class StoreroomController extends AbstractController
|
||||||
{
|
{
|
||||||
|
|
@ -995,6 +998,87 @@ class StoreroomController extends AbstractController
|
||||||
return $this->json(['id' => $pdfPid]);
|
return $this->json(['id' => $pdfPid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Route('/api/storeroom/exist/export', name: 'app_storeroom_exist_export', methods: ['POST'])]
|
||||||
|
public function app_storeroom_exist_export(Request $request, Access $access, EntityManagerInterface $entityManager): StreamedResponse
|
||||||
|
{
|
||||||
|
$params = [];
|
||||||
|
if ($content = $request->getContent()) {
|
||||||
|
$params = json_decode($content, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$acc = $access->hasRole('store');
|
||||||
|
if (!$acc) {
|
||||||
|
throw $this->createAccessDeniedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
$storeroomId = $params['storeroom'] ?? null;
|
||||||
|
if (!$storeroomId) {
|
||||||
|
throw $this->createNotFoundException('انبار انتخاب نشده است');
|
||||||
|
}
|
||||||
|
|
||||||
|
$storeroom = $entityManager->getRepository(Storeroom::class)->find($storeroomId);
|
||||||
|
if (!$storeroom) {
|
||||||
|
throw $this->createNotFoundException('انبار مورد نظر یافت نشد');
|
||||||
|
}
|
||||||
|
|
||||||
|
$items = $params['items'] ?? [];
|
||||||
|
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->setRightToLeft(true);
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'کد',
|
||||||
|
'دسته بندی',
|
||||||
|
'نام',
|
||||||
|
'واحد',
|
||||||
|
'ورودی',
|
||||||
|
'خروجی',
|
||||||
|
'موجودی انبار',
|
||||||
|
'نقطه سفارش',
|
||||||
|
'وضعیت',
|
||||||
|
];
|
||||||
|
$sheet->fromArray($headers, null, 'A1');
|
||||||
|
|
||||||
|
$rowIndex = 2;
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$commodity = $item['commodity'] ?? [];
|
||||||
|
$cat = $commodity['cat'] ?? [];
|
||||||
|
$unit = $commodity['unit'] ?? [];
|
||||||
|
$existCount = (int)($item['existCount'] ?? 0);
|
||||||
|
$orderPoint = (int)($commodity['orderPoint'] ?? 0);
|
||||||
|
$operation = $existCount < $orderPoint ? 'نیاز به شارژ انبار' : '';
|
||||||
|
|
||||||
|
$row = [
|
||||||
|
$commodity['code'] ?? '',
|
||||||
|
$cat['name'] ?? '',
|
||||||
|
$commodity['name'] ?? '',
|
||||||
|
$unit['name'] ?? '',
|
||||||
|
$item['input'] ?? 0,
|
||||||
|
$item['output'] ?? 0,
|
||||||
|
$existCount,
|
||||||
|
$orderPoint,
|
||||||
|
$operation,
|
||||||
|
];
|
||||||
|
|
||||||
|
$sheet->fromArray($row, null, 'A' . $rowIndex);
|
||||||
|
$rowIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fileName = 'موجودی_انبار_' . ($storeroom->getName() ?? 'store') . '.xlsx';
|
||||||
|
|
||||||
|
$response = new StreamedResponse(function () use ($spreadsheet) {
|
||||||
|
$writer = new Xlsx($spreadsheet);
|
||||||
|
$writer->save('php://output');
|
||||||
|
});
|
||||||
|
|
||||||
|
$response->headers->set('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||||
|
$response->headers->set('Content-Disposition', 'attachment;filename="' . $fileName . '"');
|
||||||
|
$response->headers->set('Cache-Control', 'max-age=0');
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
#[Route('/api/storeroom/ticket/complete/{id}', name: 'app_storeroom_ticket_complete', methods: ['POST'])]
|
#[Route('/api/storeroom/ticket/complete/{id}', name: 'app_storeroom_ticket_complete', methods: ['POST'])]
|
||||||
public function app_storeroom_ticket_complete(string $id, Request $request, Access $access, Log $log, EntityManagerInterface $entityManager, PluginService $pluginService): JsonResponse
|
public function app_storeroom_ticket_complete(string $id, Request $request, Access $access, Log $log, EntityManagerInterface $entityManager, PluginService $pluginService): JsonResponse
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
<td style="width:20%">
|
<td style="width:20%">
|
||||||
<h4>
|
<h4>
|
||||||
<b>تاریخ:</b>
|
<b>تاریخ:</b>
|
||||||
{{ "now"|date("Y/m/d H:i") }}</h4>
|
{{ Jdate.jdate('Y/m/d H:i', 'now') }}</h4>
|
||||||
<br/>
|
<br/>
|
||||||
<h4>
|
<h4>
|
||||||
<b>انبار:</b>
|
<b>انبار:</b>
|
||||||
|
|
@ -96,9 +96,9 @@
|
||||||
<tr class="stimol">
|
<tr class="stimol">
|
||||||
<td class="center item">{{ loop.index }}</td>
|
<td class="center item">{{ loop.index }}</td>
|
||||||
<td class="center item">{{ item.commodity.code }}</td>
|
<td class="center item">{{ item.commodity.code }}</td>
|
||||||
<td class="center item">{{ item.commodity.cat.name }}</td>
|
<td class="center item">{{ item.commodity.cat is defined and item.commodity.cat is not null ? item.commodity.cat.name : '' }}</td>
|
||||||
<td class="center item">{{ item.commodity.name }}</td>
|
<td class="center item">{{ item.commodity.name }}</td>
|
||||||
<td class="center item">{{ item.commodity.unit.name }}</td>
|
<td class="center item">{{ item.commodity.unit is defined and item.commodity.unit is not null ? item.commodity.unit.name : '' }}</td>
|
||||||
<td class="center item">{{ item.input }}</td>
|
<td class="center item">{{ item.input }}</td>
|
||||||
<td class="center item">{{ item.output }}</td>
|
<td class="center item">{{ item.output }}</td>
|
||||||
<td class="center item {% if item.existCount < 0 %}text-danger{% endif %}">
|
<td class="center item {% if item.existCount < 0 %}text-danger{% endif %}">
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,44 @@ export default defineComponent({
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const exportExcel = async () => {
|
||||||
|
if (!storeroom.value) {
|
||||||
|
alert('لطفا ابتدا انبار را انتخاب کنید')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const res = await axios.post('/api/storeroom/exist/export', {
|
||||||
|
storeroom: storeroom.value,
|
||||||
|
items: items.value,
|
||||||
|
}, { responseType: 'blob' })
|
||||||
|
|
||||||
|
const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
|
||||||
|
const url = window.URL.createObjectURL(blob)
|
||||||
|
const link = document.createElement('a')
|
||||||
|
|
||||||
|
const disposition = res.headers['content-disposition'] || res.headers['Content-Disposition']
|
||||||
|
let filename = 'storeroom_exist.xlsx'
|
||||||
|
if (disposition) {
|
||||||
|
const match = disposition.match(/filename\*=UTF-8''([^;]+)|filename="?([^";]+)"?/)
|
||||||
|
const extracted = decodeURIComponent(match?.[1] || match?.[2] || '')
|
||||||
|
if (extracted) filename = extracted
|
||||||
|
}
|
||||||
|
|
||||||
|
link.href = url
|
||||||
|
link.setAttribute('download', filename)
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
document.body.removeChild(link)
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('خطا در خروجی اکسل:', error)
|
||||||
|
alert('خطا در خروجی اکسل')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
watch(searchValue, filterItems)
|
watch(searchValue, filterItems)
|
||||||
watch(showZeroTransactions, filterItems)
|
watch(showZeroTransactions, filterItems)
|
||||||
onMounted(loadData)
|
onMounted(loadData)
|
||||||
|
|
@ -111,7 +149,8 @@ export default defineComponent({
|
||||||
headers,
|
headers,
|
||||||
loadStoreItems,
|
loadStoreItems,
|
||||||
showZeroTransactions,
|
showZeroTransactions,
|
||||||
print
|
print,
|
||||||
|
exportExcel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -145,6 +184,13 @@ export default defineComponent({
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</template>
|
</template>
|
||||||
</v-tooltip>
|
</v-tooltip>
|
||||||
|
<v-tooltip text="خروجی اکسل" location="bottom">
|
||||||
|
<template v-slot:activator="{ props }">
|
||||||
|
<v-btn v-bind="props" icon @click="exportExcel()" color="success">
|
||||||
|
<v-icon>mdi-file-excel</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
</v-tooltip>
|
||||||
</v-toolbar>
|
</v-toolbar>
|
||||||
<v-container fluid>
|
<v-container fluid>
|
||||||
<v-row>
|
<v-row>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue