Merge branch 'develop'
This commit is contained in:
commit
2c6205d01a
1 changed files with 129 additions and 1 deletions
|
|
@ -5,16 +5,19 @@ import {
|
||||||
ProductGroup,
|
ProductGroup,
|
||||||
QuotationStatus,
|
QuotationStatus,
|
||||||
RequestWorkStatus,
|
RequestWorkStatus,
|
||||||
|
PaymentStatus,
|
||||||
User,
|
User,
|
||||||
|
Invoice,
|
||||||
|
CustomerType,
|
||||||
} from "@prisma/client";
|
} from "@prisma/client";
|
||||||
import { Controller, Get, Query, Request, Route, Security, Tags } from "tsoa";
|
import { Controller, Get, Query, Request, Route, Security, Tags } from "tsoa";
|
||||||
import prisma from "../db";
|
import prisma from "../db";
|
||||||
import { createPermCondition } from "../services/permission";
|
import { createPermCondition } from "../services/permission";
|
||||||
import { RequestWithUser } from "../interfaces/user";
|
import { RequestWithUser } from "../interfaces/user";
|
||||||
import { PaymentStatus } from "../generated/kysely/types";
|
|
||||||
import { precisionRound } from "../utils/arithmetic";
|
import { precisionRound } from "../utils/arithmetic";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { json2csv } from "json-2-csv";
|
import { json2csv } from "json-2-csv";
|
||||||
|
import { isSystem } from "../utils/keycloak";
|
||||||
|
|
||||||
const permissionCondCompany = createPermCondition((_) => true);
|
const permissionCondCompany = createPermCondition((_) => true);
|
||||||
|
|
||||||
|
|
@ -638,4 +641,129 @@ export class StatsController extends Controller {
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get("customer-dept")
|
||||||
|
async reportCustomerDept(@Request() req: RequestWithUser) {
|
||||||
|
let query = prisma.$kysely
|
||||||
|
.selectFrom("Quotation")
|
||||||
|
.leftJoin("Invoice", "Quotation.id", "Invoice.quotationId")
|
||||||
|
.leftJoin("Payment", "Invoice.id", "Payment.invoiceId")
|
||||||
|
.leftJoin("CustomerBranch", "CustomerBranch.id", "Quotation.customerBranchId")
|
||||||
|
.leftJoin("Customer", "Customer.id", "CustomerBranch.customerId")
|
||||||
|
.select([
|
||||||
|
"CustomerBranch.id as customerBranchId",
|
||||||
|
"CustomerBranch.code as customerBranchCode",
|
||||||
|
"CustomerBranch.registerName as customerBranchRegisterName",
|
||||||
|
"CustomerBranch.registerNameEN as customerBranchRegisterNameEN",
|
||||||
|
"CustomerBranch.firstName as customerBranchFirstName",
|
||||||
|
"CustomerBranch.firstNameEN as customerBranchFirstNameEN",
|
||||||
|
"CustomerBranch.lastName as customerBranchFirstName",
|
||||||
|
"CustomerBranch.lastNameEN as customerBranchFirstNameEN",
|
||||||
|
"Customer.customerType",
|
||||||
|
"Quotation.id as quotationId",
|
||||||
|
"Quotation.code as quotationCode",
|
||||||
|
"Quotation.finalPrice as quotationValue",
|
||||||
|
])
|
||||||
|
.select(["Payment.paymentStatus"])
|
||||||
|
.selectAll(["Invoice"])
|
||||||
|
.distinctOn("Quotation.id");
|
||||||
|
|
||||||
|
if (!isSystem(req.user)) {
|
||||||
|
query = query.where(({ eb, exists }) =>
|
||||||
|
exists(
|
||||||
|
eb
|
||||||
|
.selectFrom("Branch")
|
||||||
|
.leftJoin("BranchUser", "BranchUser.branchId", "Branch.id")
|
||||||
|
.leftJoin("Branch as SubBranch", "SubBranch.headOfficeId", "Branch.id")
|
||||||
|
.leftJoin("BranchUser as SubBranchUser", "SubBranchUser.branchId", "SubBranch.id")
|
||||||
|
.leftJoin("Branch as HeadBranch", "HeadBranch.id", "Branch.id")
|
||||||
|
.leftJoin("BranchUser as HeadBranchUser", "HeadBranchUser.branchId", "HeadBranch.id")
|
||||||
|
.leftJoin("Branch as SubHeadBranch", "SubHeadBranch.headOfficeId", "HeadBranch.id")
|
||||||
|
.leftJoin(
|
||||||
|
"BranchUser as SubHeadBranchUser",
|
||||||
|
"SubHeadBranchUser.branchId",
|
||||||
|
"SubHeadBranch.id",
|
||||||
|
)
|
||||||
|
.where((eb) => {
|
||||||
|
const cond = [
|
||||||
|
eb("BranchUser.userId", "=", req.user.sub), // NOTE: if user belong to current branch.
|
||||||
|
eb("SubBranchUser.userId", "=", req.user.sub), // NOTE: if user belong to branch under current branch.
|
||||||
|
eb("HeadBranchUser.userId", "=", req.user.sub), // NOTE: if the current branch is under head branch user belong to.
|
||||||
|
eb("SubHeadBranchUser.userId", "=", req.user.sub), // NOTE: if the current branch is under the same head branch user belong to.
|
||||||
|
];
|
||||||
|
return eb.or(cond);
|
||||||
|
})
|
||||||
|
.select("Branch.id"),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ret = await query.execute();
|
||||||
|
const arr = ret.map((item) => {
|
||||||
|
const data: Record<string, any> = {};
|
||||||
|
for (const [key, val] of Object.entries(item)) {
|
||||||
|
if (key.startsWith("customerBranch")) {
|
||||||
|
if (!data["customerBranch"]) data["customerBranch"] = {};
|
||||||
|
data["customerBranch"][key.slice(14).slice(0, 1).toLowerCase() + key.slice(14).slice(1)] =
|
||||||
|
val;
|
||||||
|
} else if (key.startsWith("customerType")) {
|
||||||
|
data["customerBranch"]["customer"] = { customerType: val };
|
||||||
|
} else {
|
||||||
|
data[key as keyof typeof data] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data as Invoice & {
|
||||||
|
quotationId: string;
|
||||||
|
quotationCode: string;
|
||||||
|
quotationValue: number;
|
||||||
|
paymentStatus: PaymentStatus;
|
||||||
|
customerBranch: CustomerBranch & { customer: { customerType: CustomerType } };
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return arr
|
||||||
|
.reduce<
|
||||||
|
{
|
||||||
|
paid: number;
|
||||||
|
unpaid: number;
|
||||||
|
customerBranch: CustomerBranch & { customer: { customerType: CustomerType } };
|
||||||
|
_quotation: { id: string; code: string; value: number }[];
|
||||||
|
}[]
|
||||||
|
>((acc, item) => {
|
||||||
|
const exists = acc.find((v) => v.customerBranch.id === item.customerBranch.id);
|
||||||
|
|
||||||
|
const quotation = {
|
||||||
|
id: item.quotationId,
|
||||||
|
code: item.quotationCode,
|
||||||
|
value:
|
||||||
|
item.quotationValue -
|
||||||
|
(item.paymentStatus === "PaymentSuccess" && item.amount ? item.amount : 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
return acc.concat({
|
||||||
|
_quotation: [quotation],
|
||||||
|
customerBranch: item.customerBranch,
|
||||||
|
paid: item.paymentStatus === "PaymentSuccess" && item.amount ? item.amount : 0,
|
||||||
|
unpaid: quotation.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const same = exists._quotation.find((v) => v.id === item.quotationId);
|
||||||
|
|
||||||
|
if (item.paymentStatus === "PaymentSuccess" && item.amount) {
|
||||||
|
exists.paid += item.amount;
|
||||||
|
if (same) same.value -= item.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!same) exists._quotation.push(quotation);
|
||||||
|
|
||||||
|
exists.unpaid = exists._quotation.reduce((a, c) => a + c.value, 0);
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, [])
|
||||||
|
.map((v) => {
|
||||||
|
return { ...v, _quotation: undefined };
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue