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]);
|
||||
|
||||
// محاسبه تجمیعی موجودی کالا بر اساس ردیفهای حسابداری تاییدشده
|
||||
$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;
|
||||
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 = [
|
||||
$commodity->getName(),
|
||||
$commodity->getCode(),
|
||||
|
|
@ -267,7 +297,8 @@ class BackupController extends AbstractController
|
|||
$commodity->getUnit() ? $commodity->getUnit()->getName() : '',
|
||||
$commodity->getPriceBuy(),
|
||||
$commodity->getPriceSell(),
|
||||
'', // Entity Commodity فیلد موجودی ندارد
|
||||
$count,
|
||||
$nominalValue,
|
||||
$commodity->getMinOrderCount(), // حداقل سفارش
|
||||
$commodity->getDes(),
|
||||
'' // Entity Commodity فیلد تاریخ ثبت ندارد
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ use Symfony\Component\HttpFoundation\JsonResponse;
|
|||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class StoreroomController extends AbstractController
|
||||
{
|
||||
|
|
@ -995,6 +998,87 @@ class StoreroomController extends AbstractController
|
|||
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'])]
|
||||
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%">
|
||||
<h4>
|
||||
<b>تاریخ:</b>
|
||||
{{ "now"|date("Y/m/d H:i") }}</h4>
|
||||
{{ Jdate.jdate('Y/m/d H:i', 'now') }}</h4>
|
||||
<br/>
|
||||
<h4>
|
||||
<b>انبار:</b>
|
||||
|
|
@ -96,9 +96,9 @@
|
|||
<tr class="stimol">
|
||||
<td class="center item">{{ loop.index }}</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.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.output }}</td>
|
||||
<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(showZeroTransactions, filterItems)
|
||||
onMounted(loadData)
|
||||
|
|
@ -111,7 +149,8 @@ export default defineComponent({
|
|||
headers,
|
||||
loadStoreItems,
|
||||
showZeroTransactions,
|
||||
print
|
||||
print,
|
||||
exportExcel
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -145,6 +184,13 @@ export default defineComponent({
|
|||
</v-btn>
|
||||
</template>
|
||||
</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-container fluid>
|
||||
<v-row>
|
||||
|
|
|
|||
Loading…
Reference in a new issue