diff --git a/actions/companyActions.js b/actions/companyActions.js index 24d986f..dd82291 100644 --- a/actions/companyActions.js +++ b/actions/companyActions.js @@ -33,6 +33,10 @@ export const getCompanyInfo = ({ dispatch }) => }) .then((response) => { + console.log({ company: response.data }); +// const eventTrack = new CustomEvent("_track", { detail: { type: "error", title: "Ошибка", content: "Ошибка при вызове метода offerprintform" } }); +// window.dispatchEvent(eventTrack); + getEDOOperatorList({ dispatch }).then(() => {}).catch(() => {}); //console.log("getCompanyInfo", "response", response.data); diff --git a/actions/index.js b/actions/index.js index 2e6213c..f9590e2 100644 --- a/actions/index.js +++ b/actions/index.js @@ -16,4 +16,5 @@ export * from './questionnaireActions'; export * from './feedbackActions'; export * from './dealsActions'; export * from './edoActions'; -export * from './signActions'; \ No newline at end of file +export * from './signActions'; +export * from './invoicesActions'; \ No newline at end of file diff --git a/actions/invoicesActions.js b/actions/invoicesActions.js new file mode 100644 index 0000000..e4022c8 --- /dev/null +++ b/actions/invoicesActions.js @@ -0,0 +1,106 @@ +import axios from 'axios'; +import fileDownload from 'js-file-download'; + +import * as actionTypes from '../constants/actionTypes'; + +if(process.browser) +{ + FormData.prototype.appendObject = function(obj, namespace) + { + let keyName; + for (var key in obj) + { + if (obj.hasOwnProperty(key)) + { + keyName = [namespace, '[', key, ']'].join(''); + this.append(keyName, obj[key]); + } + } + }; +} + +export const getContractInvoices = ({ dispatch, number }) => +{ + return new Promise((resolve, reject) => + { + axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/contract/invoices`, { number }, + { + withCredentials: true, + }) + .then(async (response) => + { + console.log("getContractInvoices", { response: response.data }); + dispatch({ type: actionTypes.INVOICES_LIST, data: { number, invoices: response.data } }); + resolve(); + }) + .catch((error) => + { + console.error(error); + reject(); + }); + }); +} + +export const downloadInvoiceFile = ({ payload, filename }) => +{ + const url = `${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/contract/invoice/download`; + + return new Promise((resolve, reject) => + { + axios.get(url, { + params: payload, + responseType: 'blob', + }) + .then((response) => + { + fileDownload(response.data, filename); + resolve(); + }) + .catch((error) => + { + console.error("ACTION", "sign", "downloadInvoiceFile()", "ERROR"); + console.error(error); + + const eventMessage = new CustomEvent("_message", { detail: { type: "error", title: "Ошибка", content: "Ошибка при вызове метода GetWMDoc" } }); + window.dispatchEvent(eventMessage); + + reject(error.data); + }); + }); +} + +export const getInvoiceKASKO = ({ number }) => +{ + axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/contract/invoice/kasko`, { number }, + { + withCredentials: true, + }) + .then(async (response) => + { + console.log("getInvoiceKASKO", { response: response.data }); + resolve(); + }) + .catch((error) => + { + console.error(error); + reject(); + }); +} + +export const getInvoiceFinGap = ({ number }) => +{ + axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/contract/invoice/fingap`, { number }, + { + withCredentials: true, + }) + .then(async (response) => + { + console.log("getInvoiceFinGap", { response: response.data }); + resolve(); + }) + .catch((error) => + { + console.error(error); + reject(); + }); +} \ No newline at end of file diff --git a/components/DealsStatus/DealsListDeal.js b/components/DealsStatus/DealsListDeal.js index 6a5cf53..a72120a 100644 --- a/components/DealsStatus/DealsListDeal.js +++ b/components/DealsStatus/DealsListDeal.js @@ -59,7 +59,7 @@ export default class DealsListDeal extends React.Component const step = statuscode_id - 100; return ( -
+
{ onSelectDeal(opp_number, index) }}>

№ { opp_number }

@@ -79,7 +79,7 @@ export default class DealsListDeal extends React.Component

{ statuses[ statuscode_id ].title }

- +
- )) : ( -

Нет договоров

- ) } -
- { contracts.length > 0 && - ( -
- - + ) }
- ) } + ) } - _render_signingPlanContracts = () => + _render_signingPlanContracts = (type) => { const contracts = this.props.contracts['signing_plan_contracts']; const { onDealContractsUpdate, dealSelected } = this.props; console.log("_render_signingPlanContracts", { contracts }); return ( -
- { contracts.length > 0 ? - contracts.map((contract, index) => ( - - ) - ) : ( -

Нет договоров

- ) } +
+

{ type.title }

+
+
+ { contracts.length > 0 ? + contracts.map((contract, index) => ( + + ) + ) : ( +

Нет договоров

+ ) } +
+
) } - _render_signingFactContracts = () => + _render_signingFactContracts = (type) => { const contracts = this.props.contracts['signing_fact_contracts']; console.log("_render_signingFactContracts", { contracts }); return ( -
- { contracts.length > 0 ? - contracts.map((contract, index) => ( - - ) - ) : ( -

Нет договоров

- ) } +
+

{ type.title }

+
+
+ { contracts.length > 0 ? + contracts.map((contract, index) => ( + + ) + ) : ( +

Нет договоров

+ ) } +
+
) } - _render_issuedContracts = () => + _render_issuedContracts = (type) => { const contracts = this.props.contracts['issued_contracts']; console.log("_render_issuedContracts", { contracts }); return ( -
- { contracts.length > 0 ? - contracts.map((contract, index) => ( -
-
-
-

{ contract.name }

-
- { moment(contract.date).format("DD.MM.YYYY") } - { contract.brand_name } - { contract.model_name } +
+

{ type.title }

+
+
+ { contracts.length > 0 ? + contracts.map((contract, index) => ( +
+
+
+

{ contract.name }

+
+ { moment(contract.date).format("DD.MM.YYYY") } + { contract.brand_name } + { contract.model_name } +
+
-
-
- )) : ( -

Нет договоров

- ) } + )) : ( +

Нет договоров

+ ) } +
+
) } - _render_annuledContracts = () => + _render_annuledContracts = (type) => { const contracts = this.props.contracts['annulled_contracts']; console.log("_render_annuledContracts", { contracts }); - return ( -
- { contracts.length > 0 ? - contracts.map((contract, index) => ( -
-
-
-

{ contract.name }

-
- { moment(contract.date).format("DD.MM.YYYY") } - { contract.brand_name } - { contract.model_name } -
-
+ if(contracts.length > 0) + { + return ( +
+

{ type.title }

+
+
+ { contracts.map((contract, index) => ( +
+
+
+

{ contract.name }

+
+ { moment(contract.date).format("DD.MM.YYYY") } + { contract.brand_name } + { contract.model_name } +
+
+
+ )) }
- )) : ( -

Нет договоров

- ) } -
- ) +
+
+ ) + } else { + return null; + } } _render_contracts = (type) => @@ -349,31 +376,31 @@ export default class LeasingRegistration extends Step if(contracts !== undefined) { - switch (type) + switch (type.key) { case "prepared_contracts": { - return this._render_preparedContracts(); + return this._render_preparedContracts(type); } case "signing_plan_contracts": { - return this._render_signingPlanContracts(); + return this._render_signingPlanContracts(type); } case "signing_fact_contracts": { - return this._render_signingFactContracts(); + return this._render_signingFactContracts(type); } case "issued_contracts": { - return this._render_issuedContracts(); + return this._render_issuedContracts(type); } case "annulled_contracts": { - return this._render_annuledContracts(); + return this._render_annuledContracts(type); } } } @@ -399,26 +426,9 @@ export default class LeasingRegistration extends Step
- ) : ( - <> - { this.types.map((type, index) => ( -
- { edo ? ( - <> - { type.key !== "prepared_contracts" && ( -

{ type.title }

- ) } - - ) : ( -

{ type.title }

- ) } -
- { this._render_contracts(type.key) } -
-
- )) } - - ) } + ) : + this.types.map((type, index) => this._render_contracts(type) ) + }
diff --git a/constants/actionTypes.js b/constants/actionTypes.js index 2d6638e..c34d7f2 100644 --- a/constants/actionTypes.js +++ b/constants/actionTypes.js @@ -58,4 +58,6 @@ export const DEAL_RESET = 'DEAL_RESET'; export const EDO_LOADED = 'EDO_LOADED'; export const EDO_OPERATORS_LIST = 'EDO_OPERATORS_LIST'; export const EDO_INVITES_LIST = 'EDO_INVITES_LIST'; -export const EDO_RESET = 'EDO_RESET'; \ No newline at end of file +export const EDO_RESET = 'EDO_RESET'; + +export const INVOICES_LIST = 'INVOICES_LIST'; \ No newline at end of file diff --git a/css/main/style.css b/css/main/style.css index 1a70596..b02ef87 100644 --- a/css/main/style.css +++ b/css/main/style.css @@ -114,7 +114,7 @@ main .title_wrapper .right { } main .title_wrapper .company-dropdown { position: relative; - z-index: 5; + z-index: 15; } main .title_wrapper .company-dropdown .arrow { cursor: pointer; @@ -7148,3 +7148,82 @@ main .dropdown_blocks_list.zero-margin.gibdd .dropdown_block .block_body .fines_ .offer_selection:hover { text-decoration: underline; } +.deal_list_item { + cursor: pointer; +} +.contract_invoices_list { + display: flex; + gap: 40px 20px; + flex-wrap: wrap; + padding-bottom: 40px; +} +.contract_invoices_list .invoice { + max-width: 23%; + width: 23%; + min-height: 90px; + border-bottom: solid 1px var(--gray-light); + border-left: solid 1px var(--gray-light); + padding-bottom: 10px; + align-items: flex-start; + justify-content: space-between; + display: flex; + flex-direction: column; +} +@media all and (max-width: 1280px) { + .contract_invoices_list .invoice { + max-width: 31%; + width: 31%; + } +} +@media all and (max-width: 900px) { + .contract_invoices_list .invoice { + max-width: 47%; + width: 47%; + } +} +@media all and (max-width: 400px) { + .contract_invoices_list .invoice { + max-width: 100%; + width: 100%; + } +} +.contract_invoices_list .invoice p { + line-height: 15px; + color: var(--text_not_active); +} +@media all and (max-width: 1280px) { + .contract_invoices_list .invoice p { + font-size: 13px; + } +} +.contract_invoices_list .invoice .actions { + display: flex; + flex-direction: row; + align-items: flex-start; + justify-content: flex-start; + width: 100%; + padding-left: 10px; +} +.contract_invoices_list .invoice .actions .icon { + margin-top: 5px; + display: flex; + align-items: center; + justify-content: center; + width: 56px; + height: 56px; + min-width: 56px; + min-height: 56px; + position: relative; + background: url(/assets/images/icons/icon-file.svg) no-repeat left center; + background-size: contain; + padding: 0; + zoom: 0.65; +} +.contract_invoices_list .invoice .actions .icon .extension { + font-weight: 600; + font-size: 12px; + color: #fff; +} +.contract_invoices_list .invoice .actions .download { + min-width: 82px; +} diff --git a/css/main/style.less b/css/main/style.less index 4b0a379..b3d957e 100644 --- a/css/main/style.less +++ b/css/main/style.less @@ -119,619 +119,619 @@ main { } } - .company-dropdown { - position: relative; - z-index: 5; - - .arrow { - cursor: pointer; - padding-right: 22px; - background: url(/assets/images/icons/company-arrow.svg) no-repeat 100% 8px; - } - - .companies_list { - display: none; - position: absolute; - right: 0; - top: calc(100% + 28px); - width: 412px; - background: #fff; - box-shadow: 0px 4px 32px rgba(0, 0, 0, 0.16); - padding: 35px 60px 20px 6px; - - @media all and (max-width: 1279px) { - top: calc(100% + 35px); - } - - @media all and (max-width: 768px) { - top: calc(100% + 25px); - max-width: 300px; - right: 16px; - left: 0; - margin-left: 0; - } - - &.opened { - display: block; - } - - &:before { - content: ""; - display: block; - width: 0; - height: 0; - border-left: 13px solid transparent; - border-right: 13px solid transparent; - border-bottom: 24px solid #fff; - position: absolute; - top: -24px; - right: 60px; - - @media all and (max-width: 768px) { - right: auto; - left: 60px; - } - } - - .company_item { - padding-left: 60px; - margin-bottom: 20px; - cursor: pointer; - - &:not(:last-child) { - border-bottom: 1px solid #EDEFF5; - padding-bottom: 20px; - } - - @media all and (max-width: 768px) { - padding-left: 50px; - } - - &.selected { - pointer-events: none; - background: url(/assets/images/icons/icon-selected.svg) no-repeat 10px 50%; - - @media all and (max-width: 768px) { - background-size: 24px !important; - } - } - } - } - } - - .back { - padding-left: 28px; - background: url("../../public/assets/images/icons/page-back.svg") no-repeat left center; - color: var(--blue); - font-weight: 700; - margin-right: 25px; - - @media all and (max-width: 768px) { - &+.section_title { - width: 100%; - } - } - } - } - - // Главный слайдер - #main_slider { - height: 600px; - background: var(--gray-light); - padding: 0; - position: relative; - - @media all and (max-width: 1279px) { - height: 395px; - } - - .container { - position: relative; - height: 100%; - background: repeating-linear-gradient(90deg, rgba(255, 255, 255, 10%), rgba(255, 255, 255, 10%) 1px, transparent 2px, transparent 20%); - - @media all and (max-width: 768px) { - background: transparent; - } - } - - .slider_active_title { - font-weight: bold; - font-size: 43px; - line-height: 63px; - letter-spacing: 2px; - color: #fff; - max-width: 560px; - position: absolute; - top: 55px; - left: 0; - text-transform: uppercase; - font-family: 'PF Din Display Pro Bold'; - - @media all and (max-width: 1279px) { - font-size: 20px; - line-height: 35px; - max-width: 280px; - top: 25px; - } - } - - .slider_list { - position: absolute; - bottom: 0; - left: 0; - right: 0; - display: flex; - - @media all and (max-width: 1279px) { - height: 135px; - } - - @media all and (max-width: 768px) { - display: none; - } - - .slider_item { - width: 20%; - max-width: 20%; - height: 300px; - padding: 15px 25px; - display: flex; - flex-wrap: wrap; - align-items: flex-end; - align-content: flex-end; - cursor: pointer; - position: relative; - overflow: hidden; - - @media all and (max-width: 1279px) { - height: 135px; - padding: 15px 20px; - } - - &:after { - content: ""; - display: block; - position: absolute; - left: 0; - right: 0; - top: 0; - z-index: 1; - width: 100%; - height: 100%; - transform: translateY(100%); - transition: 175ms transform cubic-bezier(0.25, 0.46, 0.45, 0.94); - } - - .item_name { - font-size: 24px; - line-height: 24px; - text-transform: uppercase; - color: #fff; - width: 100%; - display: flex; - height: 86px; - align-content: center; - align-items: center; - justify-content: space-between; - transition: 175ms transform cubic-bezier(0.25, 0.46, 0.45, 0.94); - transform: translateY(57px); - position: relative; - z-index: 2; - margin-right: 15px; - font-family: 'PF Din Display Pro Bold'; - - @media all and (max-width: 1279px) { - font-size: 20px; - height: 80px; - } - - &:after { - content: ""; - display: block; - width: 22px; - min-width: 22px; - height: 14px; - background: url("/assets/images/icons/slider_arrow.svg") no-repeat center; - } - } - - a { - display: inline-block; - line-height: 40px; - color: #fff; - font-weight: 600; - transition: 175ms transform cubic-bezier(0.25, 0.46, 0.45, 0.94); - transform: translateY(57px); - position: relative; - z-index: 2; - - @media all and (max-width: 1279px) { - font-size: 13px; - } - } - - &.active { - background: currentColor; - - .item_name, - a { - transform: translateY(0px); - } - - .item_name:after { - width: 44px; - background: url("/assets/images/icons/slider_arrow-hover.svg") no-repeat center; - transform: rotate(-90deg) translate(15px, 15px); - - @media all and (max-width: 1279px) { - transform: rotate(-90deg) translate(-15px, 15px); - } - } - } - - &:hover { - - .item_name, - a { - transform: translateY(0px); - } - - &:after { - transform: translateY(0px); - background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, currentColor 100%); - } - } - - } - - .slider_navto { - width: 20%; - max-width: 20%; - height: 300px; - - a { - - background: #fff; - width: 100%; - height: 100%; - clip-path: polygon(100% 0, 0% 100%, 100% 100%); - transition: 175ms background cubic-bezier(0.25, 0.46, 0.45, 0.94); - box-sizing: border-box; - padding: 0 25px; - display: flex; - align-items: flex-end; - justify-content: flex-end; - - &:after { - content: ""; - display: block; - width: 22px; - min-width: 22px; - height: 86px; - transition: 175ms all cubic-bezier(0.25, 0.46, 0.45, 0.94); - background: url("/assets/images/icons/slider_arrow-blue.svg") no-repeat center; - } - - &:hover { - background: #04a8a4; - - &:after { - width: 90px; - background: url("/assets/images/icons/arrow-navto.svg") no-repeat center; - } - } - } - } - } - } - - // Калькулятор - #calc { - @media all and (max-width: 768px) { - background: #EDEFF5; - } - - .container { - background: url("/assets/images/calc-bg.jpg") no-repeat right center #EDEFF5; - padding: 70px 25px; - position: relative; - - &:after { - content: ""; - display: block; - position: absolute; - top: 0; - bottom: 0; - right: -100%; - width: 100%; - left: auto; - background-color: inherit; - } - - @media all and (max-width: 1279px) { - padding: 50px 25px; - } - - @media all and (max-width: 1279px) { - background: #EDEFF5; - } - - @media all and (max-width: 768px) { - padding: 25px 0; - } - } - - .calc_body { - display: flex; - justify-content: space-between; - - @media all and (max-width: 768px) { - display: block; - } - - .calc_settings { - width: 830px; - - @media all and (max-width: 1420px) { - width: calc(100% - 410px); - } - - @media all and (max-width: 1279px) { - width: calc(50% - 15px); - } - - @media all and (max-width: 768px) { - width: 100%; - } - - .settings_box { - background: rgba(255, 255, 255, 0.6); - border-radius: 4px; - height: 57px; - margin-bottom: 80px; - position: relative; - display: flex; - flex-wrap: wrap; - align-items: flex-end; - justify-content: space-between; - padding: 10px; - - output[hidden] { - display: none; - } - - &:last-child { - margin-bottom: 20px; - } - - @media all and (max-width: 1279px) { - margin-bottom: 45px; - height: 48px; - padding: 8px; - } - - p { - margin-bottom: 15px; - font-weight: 700; - - @media all and (max-width: 1279px) { - font-size: 13px; - } - - &.min { - position: absolute; - top: 65px; - font-weight: 400; - left: 10px; - margin: 0; - - @media all and (max-width: 960px) { - display: none; - } - } - - &.max { - position: absolute; - top: 65px; - font-weight: 400; - right: 10px; - margin: 0; - - @media all and (max-width: 960px) { - top: 30px; - } - } - } - - .line { - width: 100%; - background: rgb(142 148 167 / 40%); - - @media all and (max-width: 960px) { - width: calc(100% - 55px); - } - } - - .line, - .rangeslider.rangeslider--horizontal { - position: relative; - height: 5px; - z-index: 2; - - - - .active_line, - .rangeslider__fill { - background: var(--blue); - position: absolute; - left: 0; - bottom: 0; - height: 10px; - } - - .dragble, - .rangeslider__handle { - width: 1px; - height: 16px; - cursor: pointer; - position: absolute; - top: 8px; - left: 0; - - &:after { - content: ""; - display: block; - transform: rotate(45deg) translate(-6px, 6px); - width: 16px; - height: 16px; - background: var(--blue); - } - } - } - } - } - - .calc_result { - width: 350px; - align-items: stretch; - align-content: stretch; - display: flex; - flex-wrap: wrap; - - @media all and (max-width: 1420px) { - width: 320px; - } - - @media all and (max-width: 1279px) { - width: calc(50% - 15px); - } - - @media all and (max-width: 768px) { - width: 100%; - margin-top: 35px; - } - - .result_box { - width: 100%; - - p { - font-weight: 700; - - @media all and (max-width: 1279px) { - font-weight: 400; - font-size: 13px; - line-height: 20px; - margin-bottom: 20px; - } - - @media all and (max-width: 768px) { - margin-bottom: 8px; - } - - &.price { - font-size: 41px; - line-height: 1; - - sup { - font-weight: 300; - font-size: 12px; - line-height: 18px; - color: #8E94A7; - vertical-align: super; - } - - @media all and (max-width: 1279px) { - font-size: 32px; - } - - @media all and (max-width: 1279px) { - font-size: 20px; - margin-bottom: 0; - font-weight: 700; - } - } - } - - - @media all and (max-width: 768px) { - width: 50%; - } - } - - .button { - width: 100%; - align-self: center; - - @media all and (max-width: 768px) { - margin-top: 30px; - margin-bottom: 15px; - } - } - - .secondary { - align-self: flex-end; - } - } - } - } - - .news_arrows { - display: flex; - align-content: center; - - @media all and (max-width: 1279px) { - display: none !important; - } - - button { - width: 97px; - height: 28px; - background-color: var(--blue); - box-sizing: border-box; - padding: 0 10px; - transition: 175ms background ease-in-out; - - svg { - width: 8px; - height: 12px; - margin-left: auto; - - path { - stroke: #fff; - transition: 175ms stroke ease-in-out; - } - } - - &.prev {} - - &.next {} - - &:disabled, - &.slick-disabled { - cursor: default; - background-color: var(--inactive); - background-position: center; - - svg { - margin-left: 0; - - path { - stroke: #8E94A7; - } - } - } - - } - } - - #news { - .news_slider_wrapper { - @media all and (max-width: 768px) { - margin: 0 -16px; - } - } - } + .company-dropdown { + position: relative; + z-index: 15; + + .arrow { + cursor: pointer; + padding-right: 22px; + background: url(/assets/images/icons/company-arrow.svg) no-repeat 100% 8px; + } + + .companies_list { + display: none; + position: absolute; + right: 0; + top: calc(100% + 28px); + width: 412px; + background: #fff; + box-shadow: 0px 4px 32px rgba(0, 0, 0, 0.16); + padding: 35px 60px 20px 6px; + + @media all and (max-width: 1279px) { + top: calc(100% + 35px); + } + + @media all and (max-width: 768px) { + top: calc(100% + 25px); + max-width: 300px; + right: 16px; + left: 0; + margin-left: 0; + } + + &.opened { + display: block; + } + + &:before { + content: ""; + display: block; + width: 0; + height: 0; + border-left: 13px solid transparent; + border-right: 13px solid transparent; + border-bottom: 24px solid #fff; + position: absolute; + top: -24px; + right: 60px; + + @media all and (max-width: 768px) { + right: auto; + left: 60px; + } + } + + .company_item { + padding-left: 60px; + margin-bottom: 20px; + cursor: pointer; + + &:not(:last-child) { + border-bottom: 1px solid #EDEFF5; + padding-bottom: 20px; + } + + @media all and (max-width: 768px) { + padding-left: 50px; + } + + &.selected { + pointer-events: none; + background: url(/assets/images/icons/icon-selected.svg) no-repeat 10px 50%; + + @media all and (max-width: 768px) { + background-size: 24px !important; + } + } + } + } + } + + .back { + padding-left: 28px; + background: url("../../public/assets/images/icons/page-back.svg") no-repeat left center; + color: var(--blue); + font-weight: 700; + margin-right: 25px; + + @media all and (max-width: 768px) { + &+.section_title { + width: 100%; + } + } + } + } + + // Главный слайдер + #main_slider { + height: 600px; + background: var(--gray-light); + padding: 0; + position: relative; + + @media all and (max-width: 1279px) { + height: 395px; + } + + .container { + position: relative; + height: 100%; + background: repeating-linear-gradient(90deg, rgba(255, 255, 255, 10%), rgba(255, 255, 255, 10%) 1px, transparent 2px, transparent 20%); + + @media all and (max-width: 768px) { + background: transparent; + } + } + + .slider_active_title { + font-weight: bold; + font-size: 43px; + line-height: 63px; + letter-spacing: 2px; + color: #fff; + max-width: 560px; + position: absolute; + top: 55px; + left: 0; + text-transform: uppercase; + font-family: 'PF Din Display Pro Bold'; + + @media all and (max-width: 1279px) { + font-size: 20px; + line-height: 35px; + max-width: 280px; + top: 25px; + } + } + + .slider_list { + position: absolute; + bottom: 0; + left: 0; + right: 0; + display: flex; + + @media all and (max-width: 1279px) { + height: 135px; + } + + @media all and (max-width: 768px) { + display: none; + } + + .slider_item { + width: 20%; + max-width: 20%; + height: 300px; + padding: 15px 25px; + display: flex; + flex-wrap: wrap; + align-items: flex-end; + align-content: flex-end; + cursor: pointer; + position: relative; + overflow: hidden; + + @media all and (max-width: 1279px) { + height: 135px; + padding: 15px 20px; + } + + &:after { + content: ""; + display: block; + position: absolute; + left: 0; + right: 0; + top: 0; + z-index: 1; + width: 100%; + height: 100%; + transform: translateY(100%); + transition: 175ms transform cubic-bezier(0.25, 0.46, 0.45, 0.94); + } + + .item_name { + font-size: 24px; + line-height: 24px; + text-transform: uppercase; + color: #fff; + width: 100%; + display: flex; + height: 86px; + align-content: center; + align-items: center; + justify-content: space-between; + transition: 175ms transform cubic-bezier(0.25, 0.46, 0.45, 0.94); + transform: translateY(57px); + position: relative; + z-index: 2; + margin-right: 15px; + font-family: 'PF Din Display Pro Bold'; + + @media all and (max-width: 1279px) { + font-size: 20px; + height: 80px; + } + + &:after { + content: ""; + display: block; + width: 22px; + min-width: 22px; + height: 14px; + background: url("/assets/images/icons/slider_arrow.svg") no-repeat center; + } + } + + a { + display: inline-block; + line-height: 40px; + color: #fff; + font-weight: 600; + transition: 175ms transform cubic-bezier(0.25, 0.46, 0.45, 0.94); + transform: translateY(57px); + position: relative; + z-index: 2; + + @media all and (max-width: 1279px) { + font-size: 13px; + } + } + + &.active { + background: currentColor; + + .item_name, + a { + transform: translateY(0px); + } + + .item_name:after { + width: 44px; + background: url("/assets/images/icons/slider_arrow-hover.svg") no-repeat center; + transform: rotate(-90deg) translate(15px, 15px); + + @media all and (max-width: 1279px) { + transform: rotate(-90deg) translate(-15px, 15px); + } + } + } + + &:hover { + + .item_name, + a { + transform: translateY(0px); + } + + &:after { + transform: translateY(0px); + background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, currentColor 100%); + } + } + + } + + .slider_navto { + width: 20%; + max-width: 20%; + height: 300px; + + a { + + background: #fff; + width: 100%; + height: 100%; + clip-path: polygon(100% 0, 0% 100%, 100% 100%); + transition: 175ms background cubic-bezier(0.25, 0.46, 0.45, 0.94); + box-sizing: border-box; + padding: 0 25px; + display: flex; + align-items: flex-end; + justify-content: flex-end; + + &:after { + content: ""; + display: block; + width: 22px; + min-width: 22px; + height: 86px; + transition: 175ms all cubic-bezier(0.25, 0.46, 0.45, 0.94); + background: url("/assets/images/icons/slider_arrow-blue.svg") no-repeat center; + } + + &:hover { + background: #04a8a4; + + &:after { + width: 90px; + background: url("/assets/images/icons/arrow-navto.svg") no-repeat center; + } + } + } + } + } + } + + // Калькулятор + #calc { + @media all and (max-width: 768px) { + background: #EDEFF5; + } + + .container { + background: url("/assets/images/calc-bg.jpg") no-repeat right center #EDEFF5; + padding: 70px 25px; + position: relative; + + &:after { + content: ""; + display: block; + position: absolute; + top: 0; + bottom: 0; + right: -100%; + width: 100%; + left: auto; + background-color: inherit; + } + + @media all and (max-width: 1279px) { + padding: 50px 25px; + } + + @media all and (max-width: 1279px) { + background: #EDEFF5; + } + + @media all and (max-width: 768px) { + padding: 25px 0; + } + } + + .calc_body { + display: flex; + justify-content: space-between; + + @media all and (max-width: 768px) { + display: block; + } + + .calc_settings { + width: 830px; + + @media all and (max-width: 1420px) { + width: calc(100% - 410px); + } + + @media all and (max-width: 1279px) { + width: calc(50% - 15px); + } + + @media all and (max-width: 768px) { + width: 100%; + } + + .settings_box { + background: rgba(255, 255, 255, 0.6); + border-radius: 4px; + height: 57px; + margin-bottom: 80px; + position: relative; + display: flex; + flex-wrap: wrap; + align-items: flex-end; + justify-content: space-between; + padding: 10px; + + output[hidden] { + display: none; + } + + &:last-child { + margin-bottom: 20px; + } + + @media all and (max-width: 1279px) { + margin-bottom: 45px; + height: 48px; + padding: 8px; + } + + p { + margin-bottom: 15px; + font-weight: 700; + + @media all and (max-width: 1279px) { + font-size: 13px; + } + + &.min { + position: absolute; + top: 65px; + font-weight: 400; + left: 10px; + margin: 0; + + @media all and (max-width: 960px) { + display: none; + } + } + + &.max { + position: absolute; + top: 65px; + font-weight: 400; + right: 10px; + margin: 0; + + @media all and (max-width: 960px) { + top: 30px; + } + } + } + + .line { + width: 100%; + background: rgb(142 148 167 / 40%); + + @media all and (max-width: 960px) { + width: calc(100% - 55px); + } + } + + .line, + .rangeslider.rangeslider--horizontal { + position: relative; + height: 5px; + z-index: 2; + + + + .active_line, + .rangeslider__fill { + background: var(--blue); + position: absolute; + left: 0; + bottom: 0; + height: 10px; + } + + .dragble, + .rangeslider__handle { + width: 1px; + height: 16px; + cursor: pointer; + position: absolute; + top: 8px; + left: 0; + + &:after { + content: ""; + display: block; + transform: rotate(45deg) translate(-6px, 6px); + width: 16px; + height: 16px; + background: var(--blue); + } + } + } + } + } + + .calc_result { + width: 350px; + align-items: stretch; + align-content: stretch; + display: flex; + flex-wrap: wrap; + + @media all and (max-width: 1420px) { + width: 320px; + } + + @media all and (max-width: 1279px) { + width: calc(50% - 15px); + } + + @media all and (max-width: 768px) { + width: 100%; + margin-top: 35px; + } + + .result_box { + width: 100%; + + p { + font-weight: 700; + + @media all and (max-width: 1279px) { + font-weight: 400; + font-size: 13px; + line-height: 20px; + margin-bottom: 20px; + } + + @media all and (max-width: 768px) { + margin-bottom: 8px; + } + + &.price { + font-size: 41px; + line-height: 1; + + sup { + font-weight: 300; + font-size: 12px; + line-height: 18px; + color: #8E94A7; + vertical-align: super; + } + + @media all and (max-width: 1279px) { + font-size: 32px; + } + + @media all and (max-width: 1279px) { + font-size: 20px; + margin-bottom: 0; + font-weight: 700; + } + } + } + + + @media all and (max-width: 768px) { + width: 50%; + } + } + + .button { + width: 100%; + align-self: center; + + @media all and (max-width: 768px) { + margin-top: 30px; + margin-bottom: 15px; + } + } + + .secondary { + align-self: flex-end; + } + } + } + } + + .news_arrows { + display: flex; + align-content: center; + + @media all and (max-width: 1279px) { + display: none !important; + } + + button { + width: 97px; + height: 28px; + background-color: var(--blue); + box-sizing: border-box; + padding: 0 10px; + transition: 175ms background ease-in-out; + + svg { + width: 8px; + height: 12px; + margin-left: auto; + + path { + stroke: #fff; + transition: 175ms stroke ease-in-out; + } + } + + &.prev {} + + &.next {} + + &:disabled, + &.slick-disabled { + cursor: default; + background-color: var(--inactive); + background-position: center; + + svg { + margin-left: 0; + + path { + stroke: #8E94A7; + } + } + } + + } + } + + #news { + .news_slider_wrapper { + @media all and (max-width: 768px) { + margin: 0 -16px; + } + } + } .news_list, .career_list { @@ -8179,4 +8179,88 @@ main .dropdown_blocks_list.zero-margin.gibdd .dropdown_block { &:hover { text-decoration: underline; } +} + +.deal_list_item { + cursor: pointer; +} + +.contract_invoices_list { + display: flex; + gap: 40px 20px; + flex-wrap: wrap; + padding-bottom: 40px; + + .invoice { + max-width: 23%; + width: 23%; + min-height: 90px; + border-bottom: solid 1px var(--gray-light); + border-left: solid 1px var(--gray-light); + padding-bottom: 10px; + + align-items: flex-start; + justify-content: space-between; + display: flex; + flex-direction: column; + + @media all and (max-width: 1280px) { + max-width: 31%; + width: 31%; + } + + @media all and (max-width: 900px) { + max-width: 47%; + width: 47%; + } + + @media all and (max-width: 400px) { + max-width: 100%; + width: 100%; + } + + p { + line-height: 15px; + color: var(--text_not_active); + + @media all and (max-width: 1280px) { + font-size: 13px; + } + } + + .actions { + display: flex; + flex-direction: row; + align-items: flex-start; + justify-content: flex-start; + width: 100%; + padding-left: 10px; + + .icon { + margin-top: 5px; + display: flex; + align-items: center; + justify-content: center; + width: 56px; + height: 56px; + min-width: 56px; + min-height: 56px; + position: relative; + background: url(/assets/images/icons/icon-file.svg) no-repeat left center; + background-size: contain; + padding: 0; + zoom: 0.65; + + .extension { + font-weight: 600; + font-size: 12px; + color: #fff; + } + } + + .download { + min-width: 82px; + } + } + } } \ No newline at end of file diff --git a/css/var.css b/css/var.css index 8525509..cbf7c5c 100644 --- a/css/var.css +++ b/css/var.css @@ -635,7 +635,9 @@ div { margin-top: 35px; margin-bottom: 15px; } -.contracts_list_title { +.contracts_list_title, +.invoices_title, +.schedule_title { font-size: 26px; font-weight: 700; line-height: 35px; @@ -682,3 +684,9 @@ div { background: url("/assets/images/icons/close-white.svg") no-repeat center; background-size: 16px; } +.invoices_title { + margin-top: 0px; +} +.schedule_title { + margin-bottom: 15px; +} diff --git a/css/var.less b/css/var.less index baf04db..c06eb6a 100644 --- a/css/var.less +++ b/css/var.less @@ -731,4 +731,14 @@ div { background-size: 16px; } } +} + +.invoices_title { + &:extend(.contracts_list_title); + margin-top: 0px; +} + +.schedule_title { + &:extend(.contracts_list_title); + margin-bottom: 15px; } \ No newline at end of file diff --git a/pages/api/contract/invoice/download.js b/pages/api/contract/invoice/download.js new file mode 100644 index 0000000..1f7e762 --- /dev/null +++ b/pages/api/contract/invoice/download.js @@ -0,0 +1,76 @@ +import fs from 'fs'; +import axios from 'axios'; +import { Cookies } from 'react-cookie'; +import cookie from 'cookie'; +import moment from 'moment'; +import jwt from 'jsonwebtoken'; +import { inspect } from 'util'; + +export default async function handler(req, res) +{ + console.log("\n\n", "API", "/contract/invoice/download"); + + const { entity_id, code } = req.query; + const payload = { + entityId: entity_id, + reportCodes: [ code ], + createDocument: false, + openFile: true, + }; + + console.log({ payload }); + + return new Promise(async (resolve) => + { + if(req.headers.cookie !== undefined) + { + const cookies = cookie.parse(req.headers?.cookie ? req.headers?.cookie : ""); + + if(cookies.jwt !== undefined && cookies.jwt !== null) + { + var client_jwt_decoded = jwt.verify(cookies.jwt, process.env.JWT_SECRET_CLIENT); + var crm_jwt = jwt.sign({ acc_number: client_jwt_decoded.acc_number }, process.env.JWT_SECRET_CRM, { noTimestamp: true }); + + try + { + axios.post(`${ process.env.CRM_API_HOST }/File/GetWMDoc`, payload, { + responseType: 'arraybuffer', + headers: { + "Authorization": `Bearer ${ crm_jwt }`, + "Content-Type": "application/json", + }, + }) + .then((crm_response) => + { + res.status(200).send(crm_response.data); + resolve(); + }) + .catch((error) => + { + console.error(error); + console.error(error.data); + + res.status(500).send(error.data); + resolve(); + }); + } + catch(e) + { + console.error(e); + res.status(500).send(e); + resolve(); + } + } + else + { + res.status(403).send(); + resolve(); + } + } + else + { + res.status(403).send(); + resolve(); + } + }); +} \ No newline at end of file diff --git a/pages/api/contract/invoice/fingap.js b/pages/api/contract/invoice/fingap.js new file mode 100644 index 0000000..bb0d9a0 --- /dev/null +++ b/pages/api/contract/invoice/fingap.js @@ -0,0 +1,6 @@ +import CRMRequestGet from '../../../../lib/CRMRequestGet'; + +export default async function handler(req, res) +{ + await CRMRequestGet({ req, res, path: `${ process.env.CRM_API_HOST }/lk/Contract/GetFinGap`, params: { contract_number: req.body.number } }); +} \ No newline at end of file diff --git a/pages/api/contract/invoice/kasko.js b/pages/api/contract/invoice/kasko.js new file mode 100644 index 0000000..c6cd5ca --- /dev/null +++ b/pages/api/contract/invoice/kasko.js @@ -0,0 +1,6 @@ +import CRMRequestGet from '../../../../lib/CRMRequestGet'; + +export default async function handler(req, res) +{ + await CRMRequestGet({ req, res, path: `${ process.env.CRM_API_HOST }/lk/Contract/GetKasko`, params: { contract_number: req.body.number } }); +} \ No newline at end of file diff --git a/pages/api/contract/invoices.js b/pages/api/contract/invoices.js new file mode 100644 index 0000000..decc6c6 --- /dev/null +++ b/pages/api/contract/invoices.js @@ -0,0 +1,6 @@ +import CRMRequestGet from '../../../lib/CRMRequestGet'; + +export default async function handler(req, res) +{ + await CRMRequestGet({ req, res, path: `${ process.env.CRM_API_HOST }/lk/Contract/GetInvoices`, params: { contract_number: req.body.number } }); +} \ No newline at end of file diff --git a/pages/components/Layout/Account/index.js b/pages/components/Layout/Account/index.js index 7c12c01..ce8a020 100644 --- a/pages/components/Layout/Account/index.js +++ b/pages/components/Layout/Account/index.js @@ -18,6 +18,22 @@ export default class AccountLayout extends React.Component window.addEventListener("_track", this._handle_onTrack); window.addEventListener("_move", this._handle_onMove); window.addEventListener("_message", this._handle_onMessage); + + const store = global.store.getState(); + const { company, user } = store; + + console.log("LAYOUT", "CDM", { store }); + + const payload = { + userID: user.email !== undefined && user.email !== null && user.email !== "" ? user.email : user.phone, + companyID: company.active, + }; + + if(payload.companyID !== undefined && payload.companyID !== null && payload.companyID !== "") + { + console.log("LAYOUT", "CDM", { payload }); + ym(process.env.YANDEX_METRIKA_ID, 'userParams', payload); + } } console.log("CDM", { state: this.state }); @@ -37,6 +53,8 @@ export default class AccountLayout extends React.Component { //event.detail.path console.log("LAYOUT", "_handle_onTrack", { event, props: this.props }); + + console.log({ ym }); } _handle_onMove = (event) => diff --git a/pages/contract/index.js b/pages/contract/index.js index 3461b32..16d009a 100644 --- a/pages/contract/index.js +++ b/pages/contract/index.js @@ -14,10 +14,84 @@ import Footer from '../components/Footer'; import Company from "../components/Company"; import InnerMenu from "./components/InnerMenu"; -import { getContract, getContractDebtInvoiceFile, getContractInfo, getContractPenaltyInvoiceFile } from './../../actions'; +import { downloadInvoiceFile, getContract, getContractDebtInvoiceFile, getContractInfo, getContractInvoices, getContractPenaltyInvoiceFile, signGetGUIDEntity, signGetWMDoc } from './../../actions'; import AccountLayout from "../components/Layout/Account"; import ContractHeader from "./components/ContractHeader"; +class Invoice extends React.Component +{ + constructor(props) + { + super(props); + this.state = { + loading: false, + } + } + + _handle_downloadFile = () => + { + const { group, contract_number } = this.props; + + this.setState({ loading: true }, async () => + { + switch(group.type) + { + case "kaskoProlong": + { + } + break; + + case "fingapProlong": + { + + } + break; + + default: + { + const guid_result = await signGetGUIDEntity({ contract_number }); + console.log({ guid_result, code: group.code }); + await downloadInvoiceFile({ payload: { entity_id: guid_result.entityid, code: group.code }, filename: `ЛК Эволюция - договор ${ contract_number } - ${ group.title }.pdf` }); + } + break; + } + + this.setState({ loading: false }); + }); + } + + render() + { + const { group, invoices } = this.props; + const { loading } = this.state; + + console.log({ invoices }, group.type) + + if(invoices[group.type]) + { + return ( +
+

{ group.title }

+
+
+ PDF +
+
+ { loading ? ( + + ) : ( + + ) } +
+
+
+ ) + } + + return null; + } +} + class ContractSchedulePage extends React.Component { constructor(props) @@ -30,6 +104,7 @@ class ContractSchedulePage extends React.Component avans: null, debt: null, penalty: null, + invoices: {}, full: false, opened: [], debt_invoice_file_loading: false, @@ -45,6 +120,7 @@ class ContractSchedulePage extends React.Component avans: nextProps.avans, debt: nextProps.debt, penalty: nextProps.penalty, + invoices: nextProps.invoices, }; } @@ -63,11 +139,19 @@ class ContractSchedulePage extends React.Component getContractInfo({ dispatch, number }); } - getContract({ dispatch, number }).then(() => + getContract({ dispatch, number }) + .then(() => { this.setState({ loading: false }); - }).catch(() => {}); - }); + }) + .catch(() => {}); + + getContractInvoices({ dispatch, number, }) + .then(() => + { + }) + .catch(() => {}); + }); } } @@ -155,7 +239,7 @@ class ContractSchedulePage extends React.Component render() { const { number } = this.props; - const { loading, contracts_info, payments, avans, debt, penalty, full, opened, debt_invoice_file_loading, penalty_invoice_file_loading } = this.state; + const { loading, contracts_info, payments, avans, debt, penalty, full, opened, debt_invoice_file_loading, penalty_invoice_file_loading, invoices, } = this.state; let { date, car, status } = contracts_info[ number ] !== undefined ? contracts_info[ number ] : {}; @@ -166,6 +250,15 @@ class ContractSchedulePage extends React.Component //console.log("avans", avans); + const invoice_types = [ + { type: "firstPayment", title: "Счет на аванс", code: "Invoice_Payment", }, + { type: "nextPayment", title: "Счет на очередной платеж", code: "InvoicePlanPayment_attach", }, + { type: "osagoInvoice", title: "Счет ОСАГО", code: "OSAGO_Pay_contract", }, + { type: "kaskoInvoice", title: "Счет КАСКО", code: "KASKO_Pay_contract", }, + { type: "kaskoProlong", title: "Счет на пролонгацию КАСКО", }, + { type: "fingapInvoice", title: "Счет EvoSafeFinance", code: "Fingap_Pay_contract", }, + { type: "fingapProlong", title: "Счет на пролонгацию EvoSafeFinance", }, + ]; const statuses = { "NotPaid": "", @@ -203,7 +296,9 @@ class ContractSchedulePage extends React.Component
) } - {/* Вариант 1 */} + { invoices[number] !== undefined && ( +

Подготовленные счета

+ ) }
{ parseInt(debt, 10) > 0 && (
@@ -231,6 +326,12 @@ class ContractSchedulePage extends React.Component
) }
+
+ { invoices[number] !== undefined && invoice_types.map((group, index) => ( + + )) } +
+

График платежей

№ платежа
@@ -345,6 +446,7 @@ function mapStateToProps(state, ownProps) avans: state.contract.avans, debt: state.contract.debt, penalty: state.contract.penalty, + invoices: state.invoices.list, //schedule: state.payments, } } diff --git a/pages/contract/services.js b/pages/contract/services.js index 51a53fc..c6ee7fe 100644 --- a/pages/contract/services.js +++ b/pages/contract/services.js @@ -68,7 +68,7 @@ class Insurance extends React.Component id={ entry.invoice_url } filename={ `${ entry.number }.${ entry.invoice_extension}` } title="Скачать счет на оплату" - class={ "services_invoice_button" } + className={ "services_invoice_button" } log={{ contract_number: number, document_type: `${ entry.period_type !== undefined ? entry.period_type : "current" }_polis_${ type }_invoice`, diff --git a/reducers/initialState.js b/reducers/initialState.js index 94b7d01..4fa6554 100644 --- a/reducers/initialState.js +++ b/reducers/initialState.js @@ -165,6 +165,9 @@ export const defaultState = { page: 1, pages: 1, }, + invoices: { + list: {}, + }, contract: { payments: null, diff --git a/reducers/invoicesReducer.js b/reducers/invoicesReducer.js new file mode 100644 index 0000000..0b473a6 --- /dev/null +++ b/reducers/invoicesReducer.js @@ -0,0 +1,24 @@ +import * as actionTypes from '../constants/actionTypes'; +import initialState from "./initialState"; + +const invoicesReducer = (state = initialState.invoices, action) => +{ + switch (action.type) + { + case actionTypes.INVOICES_LIST: + { + const shrink = {}; + shrink[ action.data.number ] = action.data.invoices; + + return { + list: { ...state.list, ...shrink }, + }; + } + + default: { + return state; + } + } +}; + +export default invoicesReducer; \ No newline at end of file diff --git a/store/index.js b/store/index.js index 365e6b4..676e372 100644 --- a/store/index.js +++ b/store/index.js @@ -7,6 +7,7 @@ import companyReducer from '../reducers/companyReducer'; import companiesReducer from '../reducers/companiesReducer'; import contractsReducer from '../reducers/contractsReducer'; import contractReducer from '../reducers/contractReducer'; +import invoicesReducer from '../reducers/invoicesReducer'; import calendarReducer from '../reducers/calendarReducer'; import eventsReducer from '../reducers/eventsReducer'; import supportReducer from '../reducers/supportReducer'; @@ -35,6 +36,7 @@ const combinedReducer = combineReducers({ questionnaire: questionnaireReducer, deals: dealsReducer, edo: edoReducer, + invoices: invoicesReducer, }); const makeStore = (context) => @@ -52,7 +54,7 @@ const makeStore = (context) => const persistConfig = { key: 'lkevoleasing', - whitelist: [ 'auth', 'user', 'company', 'events', 'companies', 'contracts_info', 'contract_events', 'contract_fines', 'questionnaire', 'edo' ], + whitelist: [ 'auth', 'user', 'company', 'events', 'companies', 'contracts_info', 'invoices', 'contract_events', 'contract_fines', 'questionnaire', 'edo' ], storage };