Added read only invocies. Removed added reducer coe that was needed BOD-408

This commit is contained in:
Patrick Fic
2020-09-28 15:23:28 -07:00
parent cb412f377e
commit 6b6d052e74
17 changed files with 144 additions and 62 deletions

View File

@@ -1,4 +1,4 @@
<babeledit_project version="1.2" be_version="2.7.1">
<babeledit_project be_version="2.7.1" version="1.2">
<!--
BabelEdit project file
@@ -1567,6 +1567,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>exported</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>federal_tax_rate</name>
<definition_loaded>false</definition_loaded>

View File

@@ -5,7 +5,10 @@ import queryString from "query-string";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useLocation } from "react-router-dom";
import { UPDATE_BILL_LINE } from "../../graphql/bill-lines.queries";
import {
INSERT_NEW_BILL_LINES,
UPDATE_BILL_LINE,
} from "../../graphql/bill-lines.queries";
import { QUERY_BILL_BY_PK, UPDATE_BILL } from "../../graphql/bills.queries";
import AlertComponent from "../alert/alert.component";
import BillFormContainer from "../bill-form/bill-form.container";
@@ -18,6 +21,7 @@ export default function BillDetailEditcontainer() {
const [form] = Form.useForm();
const [updateLoading, setUpdateLoading] = useState(false);
const [update_bill] = useMutation(UPDATE_BILL);
const [insertBillLine] = useMutation(INSERT_NEW_BILL_LINES);
const [updateBillLine] = useMutation(UPDATE_BILL_LINE);
const { loading, error, data, refetch } = useQuery(QUERY_BILL_BY_PK, {
@@ -37,17 +41,35 @@ export default function BillDetailEditcontainer() {
billlines.forEach((il) => {
delete il.__typename;
updates.push(
updateBillLine({
variables: {
billLineId: il.id,
billLine: {
...il,
joblineid: il.joblineid === "noline" ? null : il.joblineid,
if (il.id) {
updates.push(
updateBillLine({
variables: {
billLineId: il.id,
billLine: {
...il,
joblineid: il.joblineid === "noline" ? null : il.joblineid,
},
},
},
})
);
})
);
} else {
//It's a new line, have to insert it.
updates.push(
insertBillLine({
variables: {
billLines: [
{
...il,
billid: search.billid,
joblineid: il.joblineid === "noline" ? null : il.joblineid,
},
],
},
})
);
}
});
await Promise.all(updates);
@@ -62,6 +84,9 @@ export default function BillDetailEditcontainer() {
if (error) return <AlertComponent message={error.message} type="error" />;
if (!!!search.billid) return <div>{t("bills.labels.noneselected")}</div>;
const exported = data && data.bills_by_pk && data.bills_by_pk.exported;
return (
<LoadingSkeleton loading={loading}>
<Form
@@ -94,10 +119,15 @@ export default function BillDetailEditcontainer() {
: {}
}
>
<Button htmlType="submit" loading={updateLoading} type="primary">
<Button
htmlType="submit"
disabled={exported}
loading={updateLoading}
type="primary"
>
{t("general.actions.save")}
</Button>
<BillFormContainer form={form} billEdit />
<BillFormContainer form={form} billEdit disabled={exported} />
<JobDocumentsGallery
jobId={data ? data.bills_by_pk.jobid : null}
billId={search.billid}

View File

@@ -29,6 +29,7 @@ const mapDispatchToProps = (dispatch) => ({});
export function BillFormComponent({
bodyshop,
disabled,
form,
vendorAutoCompleteOptions,
lineData,
@@ -74,7 +75,7 @@ export function BillFormComponent({
]}
>
<JobSearchSelect
disabled={billEdit}
disabled={billEdit || disabled}
onBlur={() => {
if (form.getFieldValue("jobid") !== null) {
loadLines({ variables: { id: form.getFieldValue("jobid") } });
@@ -94,6 +95,7 @@ export function BillFormComponent({
]}
>
<VendorSearchSelect
disabled={disabled}
options={vendorAutoCompleteOptions}
onSelect={handleVendorSelect}
/>
@@ -111,7 +113,7 @@ export function BillFormComponent({
},
]}
>
<Input />
<Input disabled={disabled} />
</Form.Item>
<Form.Item
label={t("bills.fields.date")}
@@ -123,7 +125,7 @@ export function BillFormComponent({
},
]}
>
<FormDatePicker />
<FormDatePicker disabled={disabled} />
</Form.Item>
<Form.Item
label={t("bills.fields.is_credit_memo")}
@@ -142,19 +144,19 @@ export function BillFormComponent({
},
]}
>
<CurrencyInput min={0} />
<CurrencyInput min={0} disabled={disabled} />
</Form.Item>
<Form.Item
label={t("bills.fields.federal_tax_rate")}
name="federal_tax_rate"
>
<CurrencyInput min={0} />
<CurrencyInput min={0} disabled={disabled} />
</Form.Item>
<Form.Item
label={t("bills.fields.state_tax_rate")}
name="state_tax_rate"
>
<CurrencyInput min={0} />
<CurrencyInput min={0} disabled={disabled} />
</Form.Item>
<Form.Item
label={t("bills.fields.local_tax_rate")}
@@ -164,7 +166,7 @@ export function BillFormComponent({
</Form.Item>
<Form.Item label={t("bills.fields.allpartslocation")} name="location">
<Select style={{ width: "10rem" }}>
<Select style={{ width: "10rem" }} disabled={disabled}>
{bodyshop.md_parts_locations.map((loc, idx) => (
<Select.Option key={idx} value={loc}>
{loc}
@@ -181,6 +183,7 @@ export function BillFormComponent({
discount={discount}
form={form}
responsibilityCenters={responsibilityCenters}
disabled={disabled}
/>
<Form.Item

View File

@@ -11,7 +11,7 @@ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
});
export function BillFormContainer({ bodyshop, form, billEdit }) {
export function BillFormContainer({ bodyshop, form, billEdit, disabled }) {
const { data: VendorAutoCompleteData } = useQuery(SEARCH_VENDOR_AUTOCOMPLETE);
const [loadLines, { data: lineData }] = useLazyQuery(
@@ -19,18 +19,17 @@ export function BillFormContainer({ bodyshop, form, billEdit }) {
);
return (
<div>
<BillFormComponent
form={form}
billEdit={billEdit}
vendorAutoCompleteOptions={
VendorAutoCompleteData && VendorAutoCompleteData.vendors
}
loadLines={loadLines}
lineData={lineData ? lineData.joblines : []}
responsibilityCenters={bodyshop.md_responsibility_centers || null}
/>
</div>
<BillFormComponent
disabled={disabled}
form={form}
billEdit={billEdit}
vendorAutoCompleteOptions={
VendorAutoCompleteData && VendorAutoCompleteData.vendors
}
loadLines={loadLines}
lineData={lineData ? lineData.joblines : []}
responsibilityCenters={bodyshop.md_responsibility_centers || null}
/>
);
}
export default connect(mapStateToProps, null)(BillFormContainer);

View File

@@ -15,6 +15,7 @@ import BillLineSearchSelect from "../bill-line-search-select/bill-line-search-se
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
export default function BillEnterModalLinesComponent({
disabled,
lineData,
discount,
form,
@@ -45,6 +46,7 @@ export default function BillEnterModalLinesComponent({
]}
>
<BillLineSearchSelect
disabled={disabled}
options={lineData}
onSelect={(value, opt) => {
setFieldsValue({
@@ -82,7 +84,7 @@ export default function BillEnterModalLinesComponent({
},
]}
>
<Input />
<Input disabled={disabled} />
</Form.Item>
<Form.Item
label={t("billlines.fields.quantity")}
@@ -95,7 +97,11 @@ export default function BillEnterModalLinesComponent({
},
]}
>
<InputNumber precision={0} min={0} />
<InputNumber
precision={0}
min={0}
disabled={disabled}
/>
</Form.Item>
<Form.Item
label={t("billlines.fields.actual")}
@@ -110,6 +116,7 @@ export default function BillEnterModalLinesComponent({
>
<CurrencyInput
min={0}
disabled={disabled}
onBlur={(e) => {
setFieldsValue({
billlines: getFieldsValue(
@@ -141,7 +148,7 @@ export default function BillEnterModalLinesComponent({
},
]}
>
<CurrencyInput min={0} />
<CurrencyInput min={0} disabled={disabled} />
</Form.Item>
<Form.Item shouldUpdate>
{() => {
@@ -172,7 +179,7 @@ export default function BillEnterModalLinesComponent({
},
]}
>
<Select style={{ width: "150px" }}>
<Select style={{ width: "150px" }} disabled={disabled}>
{responsibilityCenters.costs.map((item) => (
<Select.Option key={item.name}>
{item.name}
@@ -187,7 +194,7 @@ export default function BillEnterModalLinesComponent({
valuePropName="checked"
name={[field.name, "applicable_taxes", "federal"]}
>
<Switch />
<Switch disabled={disabled} />
</Form.Item>
<Form.Item
label={t("billlines.fields.state_tax_applicable")}
@@ -195,7 +202,7 @@ export default function BillEnterModalLinesComponent({
valuePropName="checked"
name={[field.name, "applicable_taxes", "state"]}
>
<Switch />
<Switch disabled={disabled} />
</Form.Item>
<Form.Item
label={t("billlines.fields.local_tax_applicable")}
@@ -203,7 +210,7 @@ export default function BillEnterModalLinesComponent({
valuePropName="checked"
name={[field.name, "applicable_taxes", "local"]}
>
<Switch />
<Switch disabled={disabled} />
</Form.Item>
</LayoutFormRow>
<FormListMoveArrows
@@ -212,6 +219,7 @@ export default function BillEnterModalLinesComponent({
total={fields.length}
/>
<DeleteFilled
disabled={disabled}
onClick={() => {
remove(field.name);
}}
@@ -223,6 +231,7 @@ export default function BillEnterModalLinesComponent({
))}
<Form.Item>
<Button
disabled={disabled}
onClick={() => {
add();
}}

View File

@@ -6,7 +6,7 @@ import CurrencyFormatter from "../../utils/CurrencyFormatter";
//To be used as a form element only.
const { Option } = Select;
const BillLineSearchSelect = (
{ value, onChange, options, onBlur, onSelect },
{ value, onChange, options, onBlur, onSelect, disabled },
ref
) => {
const [option, setOption] = useState(value);
@@ -20,6 +20,7 @@ const BillLineSearchSelect = (
return (
<Select
disabled={disabled}
ref={ref}
showSearch
autoFocus

View File

@@ -13,7 +13,7 @@ import { DateFormatter } from "../../utils/DateFormatter";
import { alphaSort } from "../../utils/sorters";
const mapStateToProps = createStructuredSelector({
jobRO: selectJobReadOnly,
//jobRO: selectJobReadOnly,
});
const mapDispatchToProps = (dispatch) => ({
@@ -26,7 +26,6 @@ const mapDispatchToProps = (dispatch) => ({
});
export function BillsListTableComponent({
jobRO,
job,
billsQuery,
handleOnRowClick,
@@ -94,13 +93,22 @@ export function BillsListTableComponent({
state.sortedInfo.order,
render: (text, record) => <Checkbox checked={record.is_credit_memo} />,
},
{
title: t("bills.fields.exported"),
dataIndex: "exported",
key: "exported",
sorter: (a, b) => a.exported - b.exported,
sortOrder:
state.sortedInfo.columnKey === "exported" && state.sortedInfo.order,
render: (text, record) => <Checkbox checked={record.exported} />,
},
{
title: t("general.labels.actions"),
dataIndex: "actions",
key: "actions",
render: (text, record) => (
<div>
{jobRO ? (
{record.exported ? (
<Button disabled>{t("bills.actions.edit")}</Button>
) : (
<Link
@@ -237,7 +245,7 @@ export function BillsListTableComponent({
</Descriptions.Item>
</Descriptions>
<Button
disabled={record.is_credit_memo || jobRO}
disabled={record.is_credit_memo || record.exported}
onClick={() =>
setPartsOrderContext({
actions: {},
@@ -302,7 +310,6 @@ export function BillsListTableComponent({
{job ? (
<div>
<Button
disabled={jobRO}
onClick={() => {
setBillEnterContext({
actions: { refetch: billsQuery.refetch },

View File

@@ -12,3 +12,13 @@ export const UPDATE_BILL_LINE = gql`
}
}
`;
export const INSERT_NEW_BILL_LINES = gql`
mutation INSERT_NEW_BILL_LINES($billLines: [billlines_insert_input!]!) {
insert_billlines(objects: $billLines) {
returning {
id
}
}
}
`;

View File

@@ -35,6 +35,7 @@ export const QUERY_ALL_BILLS_PAGINATED = gql`
total
invoice_number
date
exported
job {
id
ro_number
@@ -69,6 +70,7 @@ export const QUERY_BILLS_BY_JOBID = gql`
}
order_date
deliver_by
exported
parts_order_lines {
id
act_price

View File

@@ -80,7 +80,18 @@ export function BillsListPage({
sortOrder:
state.sortedInfo.columnKey === "is_credit_memo" &&
state.sortedInfo.order,
render: (text, record) => <Checkbox checked={record.is_credit_memo} />,
render: (text, record) => (
<Checkbox disabled checked={record.is_credit_memo} />
),
},
{
title: t("bills.fields.exported"),
dataIndex: "exported",
key: "exported",
sorter: (a, b) => a.exported - b.exported,
sortOrder:
state.sortedInfo.columnKey === "exported" && state.sortedInfo.order,
render: (text, record) => <Checkbox disabled checked={record.exported} />,
},
{
title: t("general.labels.actions"),

View File

@@ -43,8 +43,3 @@ export const setJobReadOnly = (bool) => ({
type: ApplicationActionTypes.SET_JOB_READONLY,
payload: bool,
});
export const setBillReadOnly = (bool) => ({
type: ApplicationActionTypes.SET_BILL_READONLY,
payload: bool,
});

View File

@@ -11,7 +11,6 @@ const INITIAL_STATE = {
error: null,
},
jobReadOnly: false,
billReadOnly: false,
};
const applicationReducer = (state = INITIAL_STATE, action) => {
@@ -65,8 +64,6 @@ const applicationReducer = (state = INITIAL_STATE, action) => {
loading: false,
};
case ApplicationActionTypes.SET_BILL_READONLY:
return { ...state, billReadOnly: action.payload };
case ApplicationActionTypes.SET_JOB_READONLY:
return { ...state, jobReadOnly: action.payload };

View File

@@ -36,8 +36,3 @@ export const selectJobReadOnly = createSelector(
[selectApplication],
(application) => application.jobReadOnly
);
export const selectBillReadOnly = createSelector(
[selectApplication],
(application) => application.billReadOnly
);

View File

@@ -8,6 +8,5 @@ const ApplicationActionTypes = {
ADD_RECENT_ITEM: "ADD_RECENT_ITEM",
SET_SELECTED_HEADER: "SET_SELECTED_HEADER",
SET_JOB_READONLY: "SET_JOB_READONLY",
SET_BILL_READONLY: "SET_BILL_READONLY",
};
export default ApplicationActionTypes;

View File

@@ -116,6 +116,7 @@
"fields": {
"allpartslocation": "Parts Bin",
"date": "Bill Date",
"exported": "Exported",
"federal_tax_rate": "Federal Tax Rate",
"invoice_number": "Invoice Number",
"is_credit_memo": "Credit Memo?",

View File

@@ -116,6 +116,7 @@
"fields": {
"allpartslocation": "",
"date": "",
"exported": "",
"federal_tax_rate": "",
"invoice_number": "",
"is_credit_memo": "",

View File

@@ -116,6 +116,7 @@
"fields": {
"allpartslocation": "",
"date": "",
"exported": "",
"federal_tax_rate": "",
"invoice_number": "",
"is_credit_memo": "",