ci: update pre-commit and apply fixes
This commit is contained in:
parent
7b2811e8bd
commit
faf0df9879
34 changed files with 1347 additions and 1319 deletions
|
|
@ -1,15 +1,14 @@
|
||||||
exclude: 'node_modules|.git'
|
exclude: 'node_modules|.git'
|
||||||
default_stages: [commit]
|
default_stages: [pre-commit]
|
||||||
fail_fast: false
|
fail_fast: false
|
||||||
|
|
||||||
|
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.3.0
|
rev: v5.0.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
files: "suppliers_portal.*"
|
files: 'suppliers_portal.*'
|
||||||
exclude: ".*json$|.*txt$|.*csv|.*md|.*svg"
|
exclude: '.*json$|.*txt$|.*csv|.*md|.*svg'
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
- id: check-merge-conflict
|
- id: check-merge-conflict
|
||||||
- id: check-ast
|
- id: check-ast
|
||||||
|
|
@ -19,49 +18,41 @@ repos:
|
||||||
- id: debug-statements
|
- id: debug-statements
|
||||||
|
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.2.0
|
rev: v0.11.7
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
name: "Run ruff linter and apply fixes"
|
name: 'Run ruff linter and apply fixes'
|
||||||
args: ["--fix"]
|
args: ['--fix']
|
||||||
|
|
||||||
- id: ruff-format
|
- id: ruff-format
|
||||||
name: "Format Python code"
|
name: 'Format Python code'
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
|
||||||
rev: v2.7.1
|
|
||||||
hooks:
|
|
||||||
- id: prettier
|
|
||||||
types_or: [javascript, vue, scss]
|
|
||||||
# Ignore any files that might contain jinja / bundles
|
|
||||||
exclude: |
|
|
||||||
(?x)^(
|
|
||||||
suppliers_portal/public/dist/.*|
|
|
||||||
.*node_modules.*|
|
|
||||||
.*boilerplate.*|
|
|
||||||
suppliers_portal/templates/includes/.*|
|
|
||||||
suppliers_portal/public/js/lib/.*
|
|
||||||
)$
|
|
||||||
|
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-eslint
|
- repo: https://github.com/pre-commit/mirrors-eslint
|
||||||
rev: v8.44.0
|
rev: v8.56.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: eslint
|
- id: eslint
|
||||||
types_or: [javascript]
|
types_or: [javascript]
|
||||||
args: ['--quiet']
|
args: ['--quiet']
|
||||||
# Ignore any files that might contain jinja / bundles
|
# Ignore any files that might contain jinja / bundles
|
||||||
exclude: |
|
exclude: |
|
||||||
(?x)^(
|
(?x)^(
|
||||||
suppliers_portal/public/dist/.*|
|
.*boilerplate.*|
|
||||||
cypress/.*|
|
.*node_modules.*|
|
||||||
.*node_modules.*|
|
cypress/.*|
|
||||||
.*boilerplate.*|
|
suppliers_portal/public/dist/.*|
|
||||||
suppliers_portal/templates/includes/.*|
|
suppliers_portal/public/js/lib/.*|
|
||||||
suppliers_portal/public/js/lib/.*
|
suppliers_portal/public/supplier-portal/assets/.*|
|
||||||
)$
|
suppliers_portal/templates/includes/.*
|
||||||
|
)$
|
||||||
|
|
||||||
|
- repo: local
|
||||||
|
hooks:
|
||||||
|
- id: prettier
|
||||||
|
name: prettier
|
||||||
|
entry: npx prettier -w . --config .prettierrc.cjs --ignore-path .prettierignore
|
||||||
|
language: system
|
||||||
|
|
||||||
ci:
|
ci:
|
||||||
autoupdate_schedule: weekly
|
autoupdate_schedule: weekly
|
||||||
skip: []
|
skip: []
|
||||||
submodules: false
|
submodules: false
|
||||||
|
|
|
||||||
222
.prettierignore
Normal file
222
.prettierignore
Normal file
|
|
@ -0,0 +1,222 @@
|
||||||
|
#-------------------------------------------------------------------------------------------------------------------
|
||||||
|
# Keep this section in sync with .gitignore
|
||||||
|
#-------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
*.pyc
|
||||||
|
*.py~
|
||||||
|
*.comp.js
|
||||||
|
*.DS_Store
|
||||||
|
locale
|
||||||
|
.wnf-lang-status
|
||||||
|
*.swp
|
||||||
|
*.egg-info
|
||||||
|
dist/
|
||||||
|
# build/
|
||||||
|
suppliers_portal/docs/current
|
||||||
|
suppliers_portal/public/dist
|
||||||
|
suppliers_portal/public/supplier-portal/assets
|
||||||
|
.vscode
|
||||||
|
.vs
|
||||||
|
node_modules
|
||||||
|
.kdev4/
|
||||||
|
*.kdev4
|
||||||
|
*debug.log
|
||||||
|
|
||||||
|
# Not Recommended, but will remove once webpack ready
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
# build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
.cypress-coverage
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
.static_storage/
|
||||||
|
.media/
|
||||||
|
local_settings.py
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# celery beat schedule file
|
||||||
|
celerybeat-schedule
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Typescript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
|
||||||
|
# next.js build output
|
||||||
|
.next
|
||||||
|
|
||||||
|
# cypress
|
||||||
|
cypress/screenshots
|
||||||
|
cypress/videos
|
||||||
|
|
||||||
|
# JetBrains IDEs
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------------------------------------------
|
||||||
|
# Prettier-specific overrides
|
||||||
|
#-------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# Package manager files
|
||||||
|
pnpm-lock.yaml
|
||||||
|
yarn.lock
|
||||||
|
package-lock.json
|
||||||
|
shrinkwrap.json
|
||||||
|
|
||||||
|
# Build outputs
|
||||||
|
lib
|
||||||
|
.github
|
||||||
|
|
||||||
|
# Prettier reformats code blocks inside Markdown, which affects rendered output
|
||||||
|
*.md
|
||||||
|
|
||||||
|
# In a Frappe context HTML files are either Jinja or Resig's microtemplate format and should not be checked
|
||||||
|
*.html
|
||||||
19
.prettierrc.cjs
Normal file
19
.prettierrc.cjs
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
module.exports = {
|
||||||
|
arrowParens: 'avoid',
|
||||||
|
bracketSameLine: true,
|
||||||
|
bracketSpacing: true,
|
||||||
|
embeddedLanguageFormatting: 'auto',
|
||||||
|
htmlWhitespaceSensitivity: 'css',
|
||||||
|
insertPragma: false,
|
||||||
|
jsxSingleQuote: false,
|
||||||
|
printWidth: 120,
|
||||||
|
proseWrap: 'preserve',
|
||||||
|
quoteProps: 'as-needed',
|
||||||
|
requirePragma: false,
|
||||||
|
semi: false,
|
||||||
|
singleQuote: true,
|
||||||
|
tabWidth: 2,
|
||||||
|
trailingComma: 'es5',
|
||||||
|
useTabs: true,
|
||||||
|
vueIndentScriptAndStyle: false,
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"semi": false,
|
"semi": false,
|
||||||
"singleQuote": true
|
"singleQuote": true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,26 @@
|
||||||
{
|
{
|
||||||
"name": "frappe-ui-frontend",
|
"name": "frappe-ui-frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build --base=/assets/suppliers_portal/supplier-portal/ && yarn copy-html-entry",
|
"build": "vite build --base=/assets/suppliers_portal/supplier-portal/ && yarn copy-html-entry",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"copy-html-entry": "cp ../suppliers_portal/public/supplier-portal/index.html ../suppliers_portal/www/supplier-portal.html"
|
"copy-html-entry": "cp ../suppliers_portal/public/supplier-portal/index.html ../suppliers_portal/www/supplier-portal.html"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bootstrap": "5.2.3",
|
"bootstrap": "5.2.3",
|
||||||
"bootstrap-icons": "^1.11.3",
|
"bootstrap-icons": "^1.11.3",
|
||||||
"feather-icons": "^4.28.0",
|
"feather-icons": "^4.28.0",
|
||||||
"frappe-ui": "^0.1.69",
|
"frappe-ui": "^0.1.69",
|
||||||
"vue": "^3.2.25",
|
"vue": "^3.2.25",
|
||||||
"vue-router": "^4.0.12"
|
"vue-router": "^4.0.12"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^2.0.0",
|
"@vitejs/plugin-vue": "^2.0.0",
|
||||||
"autoprefixer": "^10.4.2",
|
"autoprefixer": "^10.4.2",
|
||||||
"postcss": "^8.4.5",
|
"postcss": "^8.4.5",
|
||||||
"tailwindcss": "^3.0.15",
|
"tailwindcss": "^3.0.15",
|
||||||
"vite": "^2.7.2"
|
"vite": "^2.7.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
plugins: {
|
plugins: {
|
||||||
tailwindcss: {},
|
tailwindcss: {},
|
||||||
autoprefixer: {},
|
autoprefixer: {},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<router-view />
|
<router-view />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -1,152 +1,170 @@
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-Thin.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-Thin.woff?v=3.12") format("woff");
|
url('Inter-Thin.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-Thin.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-ThinItalic.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-ThinItalic.woff?v=3.12") format("woff");
|
url('Inter-ThinItalic.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-ThinItalic.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 200;
|
font-weight: 200;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-ExtraLight.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-ExtraLight.woff?v=3.12") format("woff");
|
url('Inter-ExtraLight.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-ExtraLight.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-weight: 200;
|
font-weight: 200;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-ExtraLightItalic.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-ExtraLightItalic.woff?v=3.12") format("woff");
|
url('Inter-ExtraLightItalic.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-ExtraLightItalic.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-Light.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-Light.woff?v=3.12") format("woff");
|
url('Inter-Light.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-Light.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-LightItalic.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-LightItalic.woff?v=3.12") format("woff");
|
url('Inter-LightItalic.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-LightItalic.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-Regular.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-Regular.woff?v=3.12") format("woff");
|
url('Inter-Regular.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-Regular.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-Italic.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-Italic.woff?v=3.12") format("woff");
|
url('Inter-Italic.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-Italic.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-Medium.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-Medium.woff?v=3.12") format("woff");
|
url('Inter-Medium.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-Medium.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-MediumItalic.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-MediumItalic.woff?v=3.12") format("woff");
|
url('Inter-MediumItalic.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-MediumItalic.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-SemiBold.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-SemiBold.woff?v=3.12") format("woff");
|
url('Inter-SemiBold.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-SemiBold.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-SemiBoldItalic.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-SemiBoldItalic.woff?v=3.12") format("woff");
|
url('Inter-SemiBoldItalic.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-SemiBoldItalic.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-Bold.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-Bold.woff?v=3.12") format("woff");
|
url('Inter-Bold.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-Bold.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-BoldItalic.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-BoldItalic.woff?v=3.12") format("woff");
|
url('Inter-BoldItalic.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-BoldItalic.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-ExtraBold.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-ExtraBold.woff?v=3.12") format("woff");
|
url('Inter-ExtraBold.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-ExtraBold.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-ExtraBoldItalic.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-ExtraBoldItalic.woff?v=3.12") format("woff");
|
url('Inter-ExtraBoldItalic.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-ExtraBoldItalic.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-Black.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-Black.woff?v=3.12") format("woff");
|
url('Inter-Black.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-Black.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url("Inter-BlackItalic.woff2?v=3.12") format("woff2"),
|
src:
|
||||||
url("Inter-BlackItalic.woff?v=3.12") format("woff");
|
url('Inter-BlackItalic.woff2?v=3.12') format('woff2'),
|
||||||
|
url('Inter-BlackItalic.woff?v=3.12') format('woff');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,87 +5,87 @@ import { createResource } from 'frappe-ui'
|
||||||
import { userResource } from './user'
|
import { userResource } from './user'
|
||||||
|
|
||||||
export function sessionUser() {
|
export function sessionUser() {
|
||||||
const cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
|
const cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
|
||||||
let _sessionUser = cookies.get('user_id')
|
let _sessionUser = cookies.get('user_id')
|
||||||
if (_sessionUser === 'Guest') {
|
if (_sessionUser === 'Guest') {
|
||||||
_sessionUser = null
|
_sessionUser = null
|
||||||
}
|
}
|
||||||
return _sessionUser
|
return _sessionUser
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sessionSupplierId() {
|
export function sessionSupplierId() {
|
||||||
const cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
|
const cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
|
||||||
return cookies.get('supplier_id')
|
return cookies.get('supplier_id')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sessionSupplierName() {
|
export function sessionSupplierName() {
|
||||||
const cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
|
const cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
|
||||||
return cookies.get('supplier_name')
|
return cookies.get('supplier_name')
|
||||||
}
|
}
|
||||||
|
|
||||||
export const session = reactive({
|
export const session = reactive({
|
||||||
supplier_login: createResource({
|
supplier_login: createResource({
|
||||||
url: 'suppliers_portal.suppliers_portal.api.validate_supplier_id',
|
url: 'suppliers_portal.suppliers_portal.api.validate_supplier_id',
|
||||||
makeParams({ supplier_id }) {
|
makeParams({ supplier_id }) {
|
||||||
return {
|
return {
|
||||||
supplier_id,
|
supplier_id,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSuccess(data) {
|
onSuccess(data) {
|
||||||
if (data && data.status === 'success') {
|
if (data && data.status === 'success') {
|
||||||
userResource.reload()
|
userResource.reload()
|
||||||
session.user = sessionUser()
|
session.user = sessionUser()
|
||||||
document.cookie = `supplier_id=${data.supplier_id}`
|
document.cookie = `supplier_id=${data.supplier_id}`
|
||||||
document.cookie = `supplier_name=${data.supplier_name}`
|
document.cookie = `supplier_name=${data.supplier_name}`
|
||||||
session.supplier_id = data.supplier_id
|
session.supplier_id = data.supplier_id
|
||||||
session.supplier_name = data.supplier_name
|
session.supplier_name = data.supplier_name
|
||||||
session.login.reset()
|
session.login.reset()
|
||||||
router.replace({ name: 'SupplierInvoiceList' })
|
router.replace({ name: 'SupplierInvoiceList' })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
console.error('Login failed', error)
|
console.error('Login failed', error)
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
login: createResource({
|
login: createResource({
|
||||||
url: 'login',
|
url: 'login',
|
||||||
makeParams({ email, password }) {
|
makeParams({ email, password }) {
|
||||||
return {
|
return {
|
||||||
usr: email,
|
usr: email,
|
||||||
pwd: password,
|
pwd: password,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSuccess(data) {
|
onSuccess(data) {
|
||||||
if (data) {
|
if (data) {
|
||||||
userResource.reload()
|
userResource.reload()
|
||||||
session.user = sessionUser()
|
session.user = sessionUser()
|
||||||
// clear supplier_id and supplier_name
|
// clear supplier_id and supplier_name
|
||||||
document.cookie = `supplier_id=${session.supplier_id}; expires=Thu, 01 Jan 1970 00:00:00 UTC'`;
|
document.cookie = `supplier_id=${session.supplier_id}; expires=Thu, 01 Jan 1970 00:00:00 UTC'`
|
||||||
document.cookie = `supplier_id=${session.supplier_name}; expires=Thu, 01 Jan 1970 00:00:00 UTC'`;
|
document.cookie = `supplier_id=${session.supplier_name}; expires=Thu, 01 Jan 1970 00:00:00 UTC'`
|
||||||
session.supplier_id = ''
|
session.supplier_id = ''
|
||||||
session.supplier_name = ''
|
session.supplier_name = ''
|
||||||
session.login.reset()
|
session.login.reset()
|
||||||
router.replace({ name: 'SupplierInvoiceList' })
|
router.replace({ name: 'SupplierInvoiceList' })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
console.error('Login failed', error)
|
console.error('Login failed', error)
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
logout: createResource({
|
logout: createResource({
|
||||||
url: 'logout',
|
url: 'logout',
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
document.cookie = `supplier_id=${session.supplier_id}; expires=Thu, 01 Jan 1970 00:00:00 UTC'`;
|
document.cookie = `supplier_id=${session.supplier_id}; expires=Thu, 01 Jan 1970 00:00:00 UTC'`
|
||||||
document.cookie = `supplier_id=${session.supplier_name}; expires=Thu, 01 Jan 1970 00:00:00 UTC'`;
|
document.cookie = `supplier_id=${session.supplier_name}; expires=Thu, 01 Jan 1970 00:00:00 UTC'`
|
||||||
session.supplier_id = ''
|
session.supplier_id = ''
|
||||||
session.supplier_name = ''
|
session.supplier_name = ''
|
||||||
userResource.reset()
|
userResource.reset()
|
||||||
session.user = sessionUser()
|
session.user = sessionUser()
|
||||||
router.replace({ name: 'Login' })
|
router.replace({ name: 'Login' })
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
user: sessionUser(),
|
user: sessionUser(),
|
||||||
supplier_id: sessionSupplierId(),
|
supplier_id: sessionSupplierId(),
|
||||||
supplier_name: sessionSupplierName(),
|
supplier_name: sessionSupplierName(),
|
||||||
isLoggedIn: computed(() => !!session.user),
|
isLoggedIn: computed(() => !!session.user),
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@ import router from '@/router'
|
||||||
import { createResource } from 'frappe-ui'
|
import { createResource } from 'frappe-ui'
|
||||||
|
|
||||||
export const userResource = createResource({
|
export const userResource = createResource({
|
||||||
url: 'frappe.auth.get_logged_user',
|
url: 'frappe.auth.get_logged_user',
|
||||||
cache: 'User',
|
cache: 'User',
|
||||||
onError(error) {
|
onError(error) {
|
||||||
if (error && error.exc_type === 'AuthenticationError') {
|
if (error && error.exc_type === 'AuthenticationError') {
|
||||||
router.push({ name: 'LoginPage' })
|
router.push({ name: 'LoginPage' })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
export const addDays = (date, days) => {
|
export const addDays = (date, days) => {
|
||||||
const result = new Date(date);
|
const result = new Date(date)
|
||||||
result.setDate(result.getDate() + days);
|
result.setDate(result.getDate() + days)
|
||||||
return result;
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
export const parseInvoiceTerms = (invoiceTerm) => {
|
export const parseInvoiceTerms = invoiceTerm => {
|
||||||
switch (invoiceTerm) {
|
switch (invoiceTerm) {
|
||||||
case 'NET 10':
|
case 'NET 10':
|
||||||
return 10;
|
return 10
|
||||||
case 'NET 15':
|
case 'NET 15':
|
||||||
return 15;
|
return 15
|
||||||
case 'NET 30':
|
case 'NET 30':
|
||||||
return 30;
|
return 30
|
||||||
case 'NET 45':
|
case 'NET 45':
|
||||||
return 45;
|
return 45
|
||||||
case 'NET 60':
|
case 'NET 60':
|
||||||
return 60;
|
return 60
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,7 @@ import 'bootstrap/dist/css/bootstrap.min.css'
|
||||||
import 'bootstrap'
|
import 'bootstrap'
|
||||||
import 'bootstrap-icons/font/bootstrap-icons.css'
|
import 'bootstrap-icons/font/bootstrap-icons.css'
|
||||||
|
|
||||||
|
import { Button, Card, Input, setConfig, frappeRequest, resourcesPlugin } from 'frappe-ui'
|
||||||
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
Card,
|
|
||||||
Input,
|
|
||||||
setConfig,
|
|
||||||
frappeRequest,
|
|
||||||
resourcesPlugin,
|
|
||||||
} from 'frappe-ui'
|
|
||||||
|
|
||||||
let app = createApp(App)
|
let app = createApp(App)
|
||||||
|
|
||||||
|
|
@ -29,4 +20,4 @@ app.component('Button', Button)
|
||||||
app.component('Card', Card)
|
app.component('Card', Card)
|
||||||
app.component('Input', Input)
|
app.component('Input', Input)
|
||||||
|
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|
|
||||||
|
|
@ -4,29 +4,11 @@
|
||||||
<form class="flex flex-col space-y-2 w-full" @submit.prevent="submit">
|
<form class="flex flex-col space-y-2 w-full" @submit.prevent="submit">
|
||||||
<Switch v-model="state.forAdmin" label="Login as Admin" />
|
<Switch v-model="state.forAdmin" label="Login as Admin" />
|
||||||
<div v-if="state.forAdmin">
|
<div v-if="state.forAdmin">
|
||||||
<Input
|
<Input required name="email" type="text" placeholder="username@email.com" label="User ID" />
|
||||||
required
|
<Input required name="password" type="password" placeholder="••••••" label="Password" />
|
||||||
name="email"
|
|
||||||
type="text"
|
|
||||||
placeholder="username@email.com"
|
|
||||||
label="User ID"
|
|
||||||
/>
|
|
||||||
<Input
|
|
||||||
required
|
|
||||||
name="password"
|
|
||||||
type="password"
|
|
||||||
placeholder="••••••"
|
|
||||||
label="Password"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<Input
|
<Input required name="supplier_id" type="text" placeholder="Supplier ID" label="Supplier ID" />
|
||||||
required
|
|
||||||
name="supplier_id"
|
|
||||||
type="text"
|
|
||||||
placeholder="Supplier ID"
|
|
||||||
label="Supplier ID"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<Button :loading="session.login.loading" appearance="primary">Login</Button>
|
<Button :loading="session.login.loading" appearance="primary">Login</Button>
|
||||||
<div v-if="session.login.error" class="text-red-500">
|
<div v-if="session.login.error" class="text-red-500">
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,7 @@
|
||||||
<button type="button" class="btn btn-primary btn-light">
|
<button type="button" class="btn btn-primary btn-light">
|
||||||
<router-link to="/">Cancel</router-link>
|
<router-link to="/">Cancel</router-link>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button type="button" class="btn btn-primary btn-dark" @click="saveInvoice">Save</button>
|
||||||
type="button"
|
|
||||||
class="btn btn-primary btn-dark"
|
|
||||||
@click="saveInvoice"
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -29,24 +23,19 @@
|
||||||
<div class="mb-2 row">
|
<div class="mb-2 row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="supplier_invoice_number" class="col-sm-3 col-form-label"
|
<label for="supplier_invoice_number" class="col-sm-3 col-form-label">Invoice Number</label>
|
||||||
>Invoice Number</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="supplier_invoice_number"
|
id="supplier_invoice_number"
|
||||||
v-model.number="invoiceData.supplier_invoice_number"
|
v-model.number="invoiceData.supplier_invoice_number" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="service_date" class="col-sm-3 col-form-label"
|
<label for="service_date" class="col-sm-3 col-form-label">Service Date</label>
|
||||||
>Service Date</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<TextInput
|
<TextInput
|
||||||
:type="'date'"
|
:type="'date'"
|
||||||
|
|
@ -55,8 +44,7 @@
|
||||||
placeholder="Service Date"
|
placeholder="Service Date"
|
||||||
id="service_date"
|
id="service_date"
|
||||||
:disabled="false"
|
:disabled="false"
|
||||||
v-model="invoiceData.service_date"
|
v-model="invoiceData.service_date" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -65,25 +53,20 @@
|
||||||
<div class="mb-2 row">
|
<div class="mb-2 row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="supplier_id" class="col-sm-3 col-form-label"
|
<label for="supplier_id" class="col-sm-3 col-form-label">Supplier ID</label>
|
||||||
>Supplier ID</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
readonly
|
readonly
|
||||||
class="form-control-plaintext"
|
class="form-control-plaintext"
|
||||||
id="supplier_id"
|
id="supplier_id"
|
||||||
v-model="invoiceData.supplier"
|
v-model="invoiceData.supplier" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="invoice_date" class="col-sm-3 col-form-label"
|
<label for="invoice_date" class="col-sm-3 col-form-label">Invoice Date</label>
|
||||||
>Invoice Date</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<TextInput
|
<TextInput
|
||||||
:type="'date'"
|
:type="'date'"
|
||||||
|
|
@ -92,8 +75,7 @@
|
||||||
placeholder="Invoice Date"
|
placeholder="Invoice Date"
|
||||||
id="invoice_date"
|
id="invoice_date"
|
||||||
:disabled="false"
|
:disabled="false"
|
||||||
v-model="invoiceData.invoice_date"
|
v-model="invoiceData.invoice_date" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -102,9 +84,7 @@
|
||||||
<div class="mb-2 row">
|
<div class="mb-2 row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="supplier_name" class="col-sm-3 col-form-label"
|
<label for="supplier_name" class="col-sm-3 col-form-label">Supplier Name</label>
|
||||||
>Supplier Name</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
|
@ -112,8 +92,7 @@
|
||||||
class="form-control-plaintext"
|
class="form-control-plaintext"
|
||||||
id="supplier_name"
|
id="supplier_name"
|
||||||
:value="invoiceData.supplier_name"
|
:value="invoiceData.supplier_name"
|
||||||
v-if="!isAdministrator"
|
v-if="!isAdministrator" />
|
||||||
/>
|
|
||||||
<Autocomplete
|
<Autocomplete
|
||||||
id="supplier_name"
|
id="supplier_name"
|
||||||
:options="portalSuppliers.data"
|
:options="portalSuppliers.data"
|
||||||
|
|
@ -121,27 +100,20 @@
|
||||||
:hideSearch="!invoiceData.supplier_invoice_number"
|
:hideSearch="!invoiceData.supplier_invoice_number"
|
||||||
:label="'company_name'"
|
:label="'company_name'"
|
||||||
v-model="invoiceData.supplier_name"
|
v-model="invoiceData.supplier_name"
|
||||||
v-else
|
v-else />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="invoice_terms" class="col-sm-3 col-form-label"
|
<label for="invoice_terms" class="col-sm-3 col-form-label">Invoice Terms</label>
|
||||||
>Invoice Terms</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<select
|
<select
|
||||||
class="form-select form-select-mb h-100 d-inline-block"
|
class="form-select form-select-mb h-100 d-inline-block"
|
||||||
aria-label="Invoice Terms"
|
aria-label="Invoice Terms"
|
||||||
v-model="invoiceData.invoice_terms"
|
v-model="invoiceData.invoice_terms">
|
||||||
>
|
|
||||||
<option readonly></option>
|
<option readonly></option>
|
||||||
<option
|
<option v-for="option in invoiceTermOptions" :value="option.value">
|
||||||
v-for="option in invoiceTermOptions"
|
|
||||||
:value="option.value"
|
|
||||||
>
|
|
||||||
{{ option.label }}
|
{{ option.label }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
@ -153,9 +125,7 @@
|
||||||
<div class="col"></div>
|
<div class="col"></div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="invoice_date" class="col-sm-3 col-form-label"
|
<label for="invoice_date" class="col-sm-3 col-form-label">Due Date</label>
|
||||||
>Due Date</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<TextInput
|
<TextInput
|
||||||
:type="'date'"
|
:type="'date'"
|
||||||
|
|
@ -164,8 +134,7 @@
|
||||||
placeholder="Due Date"
|
placeholder="Due Date"
|
||||||
id="due_date"
|
id="due_date"
|
||||||
:disabled="true"
|
:disabled="true"
|
||||||
v-model="invoiceDueDate"
|
v-model="invoiceDueDate" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -182,80 +151,43 @@
|
||||||
data-bs-toggle="collapse"
|
data-bs-toggle="collapse"
|
||||||
data-bs-target="#collapseOne"
|
data-bs-target="#collapseOne"
|
||||||
aria-expanded="true"
|
aria-expanded="true"
|
||||||
aria-controls="collapseOne"
|
aria-controls="collapseOne">
|
||||||
>
|
|
||||||
Service Address
|
Service Address
|
||||||
</button>
|
</button>
|
||||||
</h2>
|
</h2>
|
||||||
<div
|
<div
|
||||||
id="collapseOne"
|
id="collapseOne"
|
||||||
class="accordion-collapse collapse show"
|
class="accordion-collapse collapse show"
|
||||||
data-bs-parent="#service-address-accordion"
|
data-bs-parent="#service-address-accordion">
|
||||||
>
|
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
<div class="row mb-1">
|
<div class="row mb-1">
|
||||||
<label for="site_code" class="col-sm-3 col-form-label"
|
<label for="site_code" class="col-sm-3 col-form-label">Site Code</label>
|
||||||
>Site Code</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input type="text" class="form-control" id="site_code" v-model="invoiceData.site_code" />
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
id="site_code"
|
|
||||||
v-model="invoiceData.site_code"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1">
|
<div class="row mb-1">
|
||||||
<label for="street" class="col-sm-3 col-form-label"
|
<label for="street" class="col-sm-3 col-form-label">Street</label>
|
||||||
>Street</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input type="text" class="form-control" id="street" v-model="invoiceData.street" />
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
id="street"
|
|
||||||
v-model="invoiceData.street"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1">
|
<div class="row mb-1">
|
||||||
<label for="city" class="col-sm-3 col-form-label"
|
<label for="city" class="col-sm-3 col-form-label">City</label>
|
||||||
>City</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input type="text" class="form-control" id="city" v-model="invoiceData.city" />
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
id="city"
|
|
||||||
v-model="invoiceData.city"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1">
|
<div class="row mb-1">
|
||||||
<label for="state" class="col-sm-3 col-form-label"
|
<label for="state" class="col-sm-3 col-form-label">State</label>
|
||||||
>State</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input type="text" class="form-control" id="state" v-model="invoiceData.state" />
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
id="state"
|
|
||||||
v-model="invoiceData.state"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1">
|
<div class="row mb-1">
|
||||||
<label for="zip_code" class="col-sm-3 col-form-label"
|
<label for="zip_code" class="col-sm-3 col-form-label">Zip Code</label>
|
||||||
>Zip Code</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input type="text" class="form-control" id="zip_code" v-model="invoiceData.zip_code" />
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
id="zip_code"
|
|
||||||
v-model="invoiceData.zip_code"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -273,21 +205,14 @@
|
||||||
data-bs-toggle="collapse"
|
data-bs-toggle="collapse"
|
||||||
data-bs-target="#collapse-2"
|
data-bs-target="#collapse-2"
|
||||||
aria-expanded="true"
|
aria-expanded="true"
|
||||||
aria-controls="collapse-2"
|
aria-controls="collapse-2">
|
||||||
>
|
|
||||||
Notes
|
Notes
|
||||||
</button>
|
</button>
|
||||||
</h2>
|
</h2>
|
||||||
<div
|
<div id="collapse-2" class="accordion-collapse collapse show" data-bs-parent="#address-accordion">
|
||||||
id="collapse-2"
|
|
||||||
class="accordion-collapse collapse show"
|
|
||||||
data-bs-parent="#address-accordion"
|
|
||||||
>
|
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
<div class="row mb-1">
|
<div class="row mb-1">
|
||||||
<label for="notes" class="col-sm-3 col-form-label"
|
<label for="notes" class="col-sm-3 col-form-label">Notes</label>
|
||||||
>Notes</label
|
|
||||||
>
|
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
<Textarea
|
<Textarea
|
||||||
:variant="'subtle'"
|
:variant="'subtle'"
|
||||||
|
|
@ -295,8 +220,7 @@
|
||||||
placeholder="Enter Notes Here"
|
placeholder="Enter Notes Here"
|
||||||
:disabled="false"
|
:disabled="false"
|
||||||
v-model="invoiceData.notes"
|
v-model="invoiceData.notes"
|
||||||
id="notes"
|
id="notes" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -327,13 +251,9 @@
|
||||||
<select
|
<select
|
||||||
class="form-select form-select-mb h-100 d-inline-block"
|
class="form-select form-select-mb h-100 d-inline-block"
|
||||||
aria-label="Service Types"
|
aria-label="Service Types"
|
||||||
v-model="item.service_type"
|
v-model="item.service_type">
|
||||||
>
|
|
||||||
<option readonly></option>
|
<option readonly></option>
|
||||||
<option
|
<option v-for="option in serviceTypeOption" :value="option.value">
|
||||||
v-for="option in serviceTypeOption"
|
|
||||||
:value="option.value"
|
|
||||||
>
|
|
||||||
{{ option.label }}
|
{{ option.label }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
@ -344,27 +264,14 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-text"
|
<span class="input-group-text"><i class="bi bi-currency-dollar"></i> </span>
|
||||||
><i class="bi bi-currency-dollar"></i>
|
<input type="text" class="form-control" v-model.number="item.rate" />
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
v-model.number="item.rate"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-text"
|
<span class="input-group-text"><i class="bi bi-currency-dollar"></i> </span>
|
||||||
><i class="bi bi-currency-dollar"></i>
|
<input type="text" readonly class="form-control" v-model.number="item.amount" />
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
readonly
|
|
||||||
class="form-control"
|
|
||||||
v-model.number="item.amount"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -390,20 +297,11 @@
|
||||||
<div class="col"></div>
|
<div class="col"></div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<label for="total_amount" class="col-sm-3 col-form-label"
|
<label for="total_amount" class="col-sm-3 col-form-label">Total Amount</label>
|
||||||
>Total Amount</label
|
|
||||||
>
|
|
||||||
<div class="cols-sm-5">
|
<div class="cols-sm-5">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-text currency-fmt"
|
<span class="input-group-text currency-fmt"><i class="bi bi-currency-dollar"></i> </span>
|
||||||
><i class="bi bi-currency-dollar"></i>
|
<input type="text" readonly class="form-control" v-model.number="invoiceData.total_amount" />
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
readonly
|
|
||||||
class="form-control"
|
|
||||||
v-model.number="invoiceData.total_amount"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -492,10 +390,7 @@ const invoiceData = reactive({
|
||||||
const invoiceItems = reactive([])
|
const invoiceItems = reactive([])
|
||||||
let invoiceDueDate = computed(() => {
|
let invoiceDueDate = computed(() => {
|
||||||
if (invoiceData.invoice_terms) {
|
if (invoiceData.invoice_terms) {
|
||||||
let result = addDays(
|
let result = addDays(invoiceData.invoice_date, parseInvoiceTerms(invoiceData.invoice_terms))
|
||||||
invoiceData.invoice_date,
|
|
||||||
parseInvoiceTerms(invoiceData.invoice_terms),
|
|
||||||
)
|
|
||||||
// return as string
|
// return as string
|
||||||
return result.toISOString().split('T')[0]
|
return result.toISOString().split('T')[0]
|
||||||
}
|
}
|
||||||
|
|
@ -513,7 +408,7 @@ const addRow = () => {
|
||||||
invoiceItems.push(rowObject)
|
invoiceItems.push(rowObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteRow = (index) => {
|
const deleteRow = index => {
|
||||||
invoiceItems.splice(index, 1)
|
invoiceItems.splice(index, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -535,7 +430,7 @@ const saveInvoice = () => {
|
||||||
state: invoiceData.state,
|
state: invoiceData.state,
|
||||||
zip_code: invoiceData.zip_code,
|
zip_code: invoiceData.zip_code,
|
||||||
notes: invoiceData.notes,
|
notes: invoiceData.notes,
|
||||||
supplier_invoice_items: invoiceItems.map((item) => {
|
supplier_invoice_items: invoiceItems.map(item => {
|
||||||
return {
|
return {
|
||||||
service_type: item.service_type,
|
service_type: item.service_type,
|
||||||
quantity: item.quantity,
|
quantity: item.quantity,
|
||||||
|
|
@ -554,11 +449,11 @@ portalSuppliers.fetch()
|
||||||
// watch for changes in invoiceData.supplier_name
|
// watch for changes in invoiceData.supplier_name
|
||||||
watch(
|
watch(
|
||||||
() => invoiceData.supplier_name,
|
() => invoiceData.supplier_name,
|
||||||
(newVal) => {
|
newVal => {
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
invoiceData.supplier = newVal.value
|
invoiceData.supplier = newVal.value
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,35 +22,24 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div :class="invoice.doc.supplier_invoice_items ? 'container border-bottom pb-3' : 'container pb-3'">
|
||||||
:class="
|
|
||||||
invoice.doc.supplier_invoice_items
|
|
||||||
? 'container border-bottom pb-3'
|
|
||||||
: 'container pb-3'
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div class="mb-1 row">
|
<div class="mb-1 row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="suppplier_id" class="col-sm-3 col-form-label"
|
<label for="suppplier_id" class="col-sm-3 col-form-label">Supplier ID</label>
|
||||||
>Supplier ID</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
readonly
|
readonly
|
||||||
class="form-control-plaintext"
|
class="form-control-plaintext"
|
||||||
id="suppplier_id"
|
id="suppplier_id"
|
||||||
:value="invoice.doc.supplier"
|
:value="invoice.doc.supplier" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row mb-1">
|
<div class="row mb-1">
|
||||||
<label for="service_date" class="col-sm-3 col-form-label"
|
<label for="service_date" class="col-sm-3 col-form-label">Service Date</label>
|
||||||
>Service Date</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<TextInput
|
<TextInput
|
||||||
:type="'date'"
|
:type="'date'"
|
||||||
|
|
@ -59,8 +48,7 @@
|
||||||
placeholder="Payment Date"
|
placeholder="Payment Date"
|
||||||
id="service_date"
|
id="service_date"
|
||||||
:disabled="true"
|
:disabled="true"
|
||||||
v-model="invoice.doc.service_date"
|
v-model="invoice.doc.service_date" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -68,25 +56,20 @@
|
||||||
<div class="mb-1 row">
|
<div class="mb-1 row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="suppplier_name" class="col-sm-3 col-form-label"
|
<label for="suppplier_name" class="col-sm-3 col-form-label">Supplier Name</label>
|
||||||
>Supplier Name</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
readonly
|
readonly
|
||||||
class="form-control-plaintext"
|
class="form-control-plaintext"
|
||||||
id="suppplier_name"
|
id="suppplier_name"
|
||||||
:value="invoice.doc.supplier_name"
|
:value="invoice.doc.supplier_name" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row mb-1">
|
<div class="row mb-1">
|
||||||
<label for="invoice_date" class="col-sm-3 col-form-label"
|
<label for="invoice_date" class="col-sm-3 col-form-label">Invoice Date</label>
|
||||||
>Invoice Date</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<TextInput
|
<TextInput
|
||||||
:type="'date'"
|
:type="'date'"
|
||||||
|
|
@ -95,8 +78,7 @@
|
||||||
placeholder="Invoice Date"
|
placeholder="Invoice Date"
|
||||||
id="invoice_date"
|
id="invoice_date"
|
||||||
:disabled="true"
|
:disabled="true"
|
||||||
v-model="invoice.doc.invoice_date"
|
v-model="invoice.doc.invoice_date" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -114,8 +96,7 @@
|
||||||
placeholder="Due Date"
|
placeholder="Due Date"
|
||||||
id="due_date"
|
id="due_date"
|
||||||
:disabled="true"
|
:disabled="true"
|
||||||
v-model="invoice.doc.due_date"
|
v-model="invoice.doc.due_date" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -124,17 +105,14 @@
|
||||||
<div class="col"></div>
|
<div class="col"></div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="invoice_terms" class="col-sm-3 col-form-label"
|
<label for="invoice_terms" class="col-sm-3 col-form-label">Invoice Terms</label>
|
||||||
>Invoice Terms</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
readonly
|
readonly
|
||||||
class="form-control-plaintext h-100 d-inline-block"
|
class="form-control-plaintext h-100 d-inline-block"
|
||||||
id="invoice_terms"
|
id="invoice_terms"
|
||||||
:value="invoice.doc.invoice_terms"
|
:value="invoice.doc.invoice_terms" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -150,85 +128,65 @@
|
||||||
data-bs-toggle="collapse"
|
data-bs-toggle="collapse"
|
||||||
data-bs-target="#collapseOne"
|
data-bs-target="#collapseOne"
|
||||||
aria-expanded="true"
|
aria-expanded="true"
|
||||||
aria-controls="collapseOne"
|
aria-controls="collapseOne">
|
||||||
>
|
|
||||||
Service Address
|
Service Address
|
||||||
</button>
|
</button>
|
||||||
</h2>
|
</h2>
|
||||||
<div
|
<div id="collapseOne" class="accordion-collapse collapse" data-bs-parent="#service-address-accordion">
|
||||||
id="collapseOne"
|
|
||||||
class="accordion-collapse collapse"
|
|
||||||
data-bs-parent="#service-address-accordion"
|
|
||||||
>
|
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
<div class="row mb-1">
|
<div class="row mb-1">
|
||||||
<label for="site_code" class="col-sm-3 col-form-label"
|
<label for="site_code" class="col-sm-3 col-form-label">Site Code</label>
|
||||||
>Site Code</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
readonly
|
readonly
|
||||||
class="form-control-plaintext"
|
class="form-control-plaintext"
|
||||||
id="site_code"
|
id="site_code"
|
||||||
:value="invoice.doc.site_code"
|
:value="invoice.doc.site_code" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1">
|
<div class="row mb-1">
|
||||||
<label for="street" class="col-sm-3 col-form-label"
|
<label for="street" class="col-sm-3 col-form-label">Street</label>
|
||||||
>Street</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
readonly
|
readonly
|
||||||
class="form-control-plaintext"
|
class="form-control-plaintext"
|
||||||
id="street"
|
id="street"
|
||||||
:value="invoice.doc.street"
|
:value="invoice.doc.street" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1">
|
<div class="row mb-1">
|
||||||
<label for="city" class="col-sm-3 col-form-label"
|
<label for="city" class="col-sm-3 col-form-label">City</label>
|
||||||
>City</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
readonly
|
readonly
|
||||||
class="form-control-plaintext"
|
class="form-control-plaintext"
|
||||||
id="city"
|
id="city"
|
||||||
:value="invoice.doc.city"
|
:value="invoice.doc.city" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1">
|
<div class="row mb-1">
|
||||||
<label for="state" class="col-sm-3 col-form-label"
|
<label for="state" class="col-sm-3 col-form-label">State</label>
|
||||||
>State</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
readonly
|
readonly
|
||||||
class="form-control-plaintext"
|
class="form-control-plaintext"
|
||||||
id="state"
|
id="state"
|
||||||
:value="invoice.doc.state"
|
:value="invoice.doc.state" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1">
|
<div class="row mb-1">
|
||||||
<label for="zip_code" class="col-sm-3 col-form-label"
|
<label for="zip_code" class="col-sm-3 col-form-label">Zip Code</label>
|
||||||
>Zip Code</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
readonly
|
readonly
|
||||||
class="form-control-plaintext"
|
class="form-control-plaintext"
|
||||||
id="zip_code"
|
id="zip_code"
|
||||||
:value="invoice.doc.zip_code"
|
:value="invoice.doc.zip_code" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -246,21 +204,14 @@
|
||||||
data-bs-toggle="collapse"
|
data-bs-toggle="collapse"
|
||||||
data-bs-target="#collapse-2"
|
data-bs-target="#collapse-2"
|
||||||
aria-expanded="true"
|
aria-expanded="true"
|
||||||
aria-controls="collapse-2"
|
aria-controls="collapse-2">
|
||||||
>
|
|
||||||
Notes
|
Notes
|
||||||
</button>
|
</button>
|
||||||
</h2>
|
</h2>
|
||||||
<div
|
<div id="collapse-2" class="accordion-collapse collapse" data-bs-parent="#address-accordion">
|
||||||
id="collapse-2"
|
|
||||||
class="accordion-collapse collapse"
|
|
||||||
data-bs-parent="#address-accordion"
|
|
||||||
>
|
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
<div class="row mb-1">
|
<div class="row mb-1">
|
||||||
<label for="notes" class="col-sm-4 col-form-label"
|
<label for="notes" class="col-sm-4 col-form-label">Notes</label>
|
||||||
>Notes</label
|
|
||||||
>
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<Textarea
|
<Textarea
|
||||||
:variant="'subtle'"
|
:variant="'subtle'"
|
||||||
|
|
@ -269,8 +220,7 @@
|
||||||
:disabled="true"
|
:disabled="true"
|
||||||
v-model="invoice.doc.notes"
|
v-model="invoice.doc.notes"
|
||||||
label=""
|
label=""
|
||||||
id="notes"
|
id="notes" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -293,10 +243,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="table-group-divider">
|
<tbody class="table-group-divider">
|
||||||
<tr
|
<tr v-for="(item, index) in invoice.doc.supplier_invoice_items" :key="item.name">
|
||||||
v-for="(item, index) in invoice.doc.supplier_invoice_items"
|
|
||||||
:key="item.name"
|
|
||||||
>
|
|
||||||
<th scope="row">{{ index + 1 }}</th>
|
<th scope="row">{{ index + 1 }}</th>
|
||||||
<td>{{ item.service_type }}</td>
|
<td>{{ item.service_type }}</td>
|
||||||
<td>{{ item.quantity }}</td>
|
<td>{{ item.quantity }}</td>
|
||||||
|
|
@ -312,20 +259,11 @@
|
||||||
<div class="col"></div>
|
<div class="col"></div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<label for="total_amount" class="col-sm-3 col-form-label"
|
<label for="total_amount" class="col-sm-3 col-form-label">Total Amount</label>
|
||||||
>Total Amount</label
|
|
||||||
>
|
|
||||||
<div class="cols-sm-5">
|
<div class="cols-sm-5">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-text"
|
<span class="input-group-text"><i class="bi bi-currency-dollar"></i> </span>
|
||||||
><i class="bi bi-currency-dollar"></i>
|
<input type="text" readonly class="form-control" v-model.number="invoice.doc.total_amount" />
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
readonly
|
|
||||||
class="form-control"
|
|
||||||
v-model.number="invoice.doc.total_amount"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,7 @@
|
||||||
<router-link to="/invoices/new">
|
<router-link to="/invoices/new">
|
||||||
<button type="button" class="btn btn-primary btn-dark">New</button>
|
<button type="button" class="btn btn-primary btn-dark">New</button>
|
||||||
</router-link>
|
</router-link>
|
||||||
<button
|
<button type="button" class="btn btn-primary btn-dark" @click="session.logout.submit">Logout</button>
|
||||||
type="button"
|
|
||||||
class="btn btn-primary btn-dark"
|
|
||||||
@click="session.logout.submit"
|
|
||||||
>
|
|
||||||
Logout
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,49 +3,49 @@ import { session } from './data/session'
|
||||||
import { userResource } from '@/data/user'
|
import { userResource } from '@/data/user'
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
name: 'Login',
|
name: 'Login',
|
||||||
path: '/login',
|
path: '/login',
|
||||||
component: () => import('@/pages/Login.vue'),
|
component: () => import('@/pages/Login.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'SupplierInvoiceList',
|
name: 'SupplierInvoiceList',
|
||||||
path: '/',
|
path: '/',
|
||||||
component: () => import('@/pages/SupplierInvoiceList.vue'),
|
component: () => import('@/pages/SupplierInvoiceList.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'SupplierInvoice',
|
name: 'SupplierInvoice',
|
||||||
path: '/invoices/:supplierInvoiceNumber',
|
path: '/invoices/:supplierInvoiceNumber',
|
||||||
component: () => import('@/pages/SupplierInvoice.vue'),
|
component: () => import('@/pages/SupplierInvoice.vue'),
|
||||||
props: true,
|
props: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'SupplierInvoiceCreate',
|
name: 'SupplierInvoiceCreate',
|
||||||
path: '/invoices/new',
|
path: '/invoices/new',
|
||||||
component: () => import('@/pages/NewInvoice.vue'),
|
component: () => import('@/pages/NewInvoice.vue'),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
let router = createRouter({
|
let router = createRouter({
|
||||||
history: createWebHistory('/supplier-portal'),
|
history: createWebHistory('/supplier-portal'),
|
||||||
routes,
|
routes,
|
||||||
})
|
})
|
||||||
|
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
let isLoggedIn = session.isLoggedIn
|
let isLoggedIn = session.isLoggedIn
|
||||||
try {
|
try {
|
||||||
await userResource.promise
|
await userResource.promise
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
isLoggedIn = false
|
isLoggedIn = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to.name === 'Login' && isLoggedIn) {
|
if (to.name === 'Login' && isLoggedIn) {
|
||||||
next({ name: 'SupplierInvoiceList' })
|
next({ name: 'SupplierInvoiceList' })
|
||||||
} else if (to.name !== 'Login' && !isLoggedIn) {
|
} else if (to.name !== 'Login' && !isLoggedIn) {
|
||||||
next({ name: 'Login' })
|
next({ name: 'Login' })
|
||||||
} else {
|
} else {
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,16 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
presets: [
|
presets: [require('frappe-ui/src/utils/tailwind.config')],
|
||||||
require('frappe-ui/src/utils/tailwind.config')
|
content: [
|
||||||
],
|
'./index.html',
|
||||||
content: [
|
'./src/**/*.{vue,js,ts,jsx,tsx}',
|
||||||
"./index.html",
|
'./node_modules/frappe-ui/src/components/**/*.{vue,js,ts,jsx,tsx}',
|
||||||
"./src/**/*.{vue,js,ts,jsx,tsx}",
|
],
|
||||||
"./node_modules/frappe-ui/src/components/**/*.{vue,js,ts,jsx,tsx}",
|
theme: {
|
||||||
],
|
extend: {
|
||||||
theme: {
|
container: {
|
||||||
extend: {
|
center: true,
|
||||||
container: {
|
},
|
||||||
center: true,
|
},
|
||||||
}
|
},
|
||||||
},
|
plugins: [],
|
||||||
},
|
|
||||||
plugins: [],
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,18 +5,18 @@ import frappeui from 'frappe-ui/vite'
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [frappeui(), vue()],
|
plugins: [frappeui(), vue()],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': path.resolve(__dirname, 'src'),
|
'@': path.resolve(__dirname, 'src'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
outDir: `../${path.basename(path.resolve('..'))}/public/supplier-portal`,
|
outDir: `../${path.basename(path.resolve('..'))}/public/supplier-portal`,
|
||||||
emptyOutDir: true,
|
emptyOutDir: true,
|
||||||
target: 'es2015',
|
target: 'es2015',
|
||||||
},
|
},
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
include: ['frappe-ui > feather-icons', 'showdown', 'engine.io-client'],
|
include: ['frappe-ui > feather-icons', 'showdown', 'engine.io-client'],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,6 @@
|
||||||
<div id="popovers"></div>
|
<div id="popovers"></div>
|
||||||
|
|
||||||
<script> window.csrf_token = '{{ csrf_token }}'; </script>
|
<script> window.csrf_token = '{{ csrf_token }}'; </script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,18 @@ import frappe
|
||||||
|
|
||||||
@frappe.whitelist(allow_guest=True)
|
@frappe.whitelist(allow_guest=True)
|
||||||
def validate_supplier_id(supplier_id: str) -> dict:
|
def validate_supplier_id(supplier_id: str) -> dict:
|
||||||
if frappe.db.exists("Supplier", {"name": supplier_id}):
|
if frappe.db.exists("Supplier", {"name": supplier_id}):
|
||||||
user = frappe.get_doc("User", f"{supplier_id}@supplier-portal.com")
|
user = frappe.get_doc("User", f"{supplier_id}@supplier-portal.com")
|
||||||
portal_supplier = frappe.get_doc("Supplier", supplier_id)
|
portal_supplier = frappe.get_doc("Supplier", supplier_id)
|
||||||
# login user
|
# login user
|
||||||
frappe.local.login_manager.user = user.name
|
frappe.local.login_manager.user = user.name
|
||||||
frappe.local.login_manager.post_login()
|
frappe.local.login_manager.post_login()
|
||||||
return {
|
return {
|
||||||
"status": "success",
|
"status": "success",
|
||||||
"message": "User logged in successfully",
|
"message": "User logged in successfully",
|
||||||
"supplier_id": supplier_id,
|
"supplier_id": supplier_id,
|
||||||
"supplier_name": portal_supplier.company_name,
|
"supplier_name": portal_supplier.company_name,
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
frappe.local.response["http_status_code"] = 404
|
frappe.local.response["http_status_code"] = 404
|
||||||
frappe.throw("Supplier not found", frappe.AuthenticationError)
|
frappe.throw("Supplier not found", frappe.AuthenticationError)
|
||||||
|
|
|
||||||
|
|
@ -1,47 +1,42 @@
|
||||||
{
|
{
|
||||||
"actions": [],
|
"actions": [],
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"creation": "2024-10-09 16:28:25.879209",
|
"creation": "2024-10-09 16:28:25.879209",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": ["payment_reference_number", "payment_reference_date", "column_break_nukw", "paid_amount"],
|
||||||
"payment_reference_number",
|
"fields": [
|
||||||
"payment_reference_date",
|
{
|
||||||
"column_break_nukw",
|
"fieldname": "payment_reference_number",
|
||||||
"paid_amount"
|
"fieldtype": "Data",
|
||||||
],
|
"label": "Reference Number"
|
||||||
"fields": [
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "payment_reference_number",
|
"fieldname": "payment_reference_date",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Date",
|
||||||
"label": "Reference Number"
|
"label": "Payment Date"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "payment_reference_date",
|
"fieldname": "column_break_nukw",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Column Break"
|
||||||
"label": "Payment Date"
|
},
|
||||||
},
|
{
|
||||||
{
|
"fieldname": "paid_amount",
|
||||||
"fieldname": "column_break_nukw",
|
"fieldtype": "Currency",
|
||||||
"fieldtype": "Column Break"
|
"label": "Amount"
|
||||||
},
|
}
|
||||||
{
|
],
|
||||||
"fieldname": "paid_amount",
|
"index_web_pages_for_search": 1,
|
||||||
"fieldtype": "Currency",
|
"istable": 1,
|
||||||
"label": "Amount"
|
"links": [],
|
||||||
}
|
"modified": "2024-10-12 07:16:26.416034",
|
||||||
],
|
"modified_by": "Administrator",
|
||||||
"index_web_pages_for_search": 1,
|
"module": "Suppliers Portal",
|
||||||
"istable": 1,
|
"name": "Invoice Payment References",
|
||||||
"links": [],
|
"owner": "Administrator",
|
||||||
"modified": "2024-10-12 07:16:26.416034",
|
"permissions": [],
|
||||||
"modified_by": "Administrator",
|
"sort_field": "creation",
|
||||||
"module": "Suppliers Portal",
|
"sort_order": "DESC",
|
||||||
"name": "Invoice Payment References",
|
"states": []
|
||||||
"owner": "Administrator",
|
}
|
||||||
"permissions": [],
|
|
||||||
"sort_field": "creation",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"states": []
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,216 +1,216 @@
|
||||||
{
|
{
|
||||||
"actions": [],
|
"actions": [],
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "field:supplier_invoice_number",
|
"autoname": "field:supplier_invoice_number",
|
||||||
"creation": "2024-09-24 02:44:02.596278",
|
"creation": "2024-09-24 02:44:02.596278",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"supplier_invoice_number",
|
"supplier_invoice_number",
|
||||||
"supplier",
|
"supplier",
|
||||||
"supplier_name",
|
"supplier_name",
|
||||||
"column_break_yjtl",
|
"column_break_yjtl",
|
||||||
"service_date",
|
"service_date",
|
||||||
"invoice_date",
|
"invoice_date",
|
||||||
"invoice_terms",
|
"invoice_terms",
|
||||||
"due_date",
|
"due_date",
|
||||||
"status",
|
"status",
|
||||||
"section_break_swkm",
|
"section_break_swkm",
|
||||||
"supplier_invoice_items",
|
"supplier_invoice_items",
|
||||||
"section_break_slsq",
|
"section_break_slsq",
|
||||||
"payment_references",
|
"payment_references",
|
||||||
"section_break_ajbe",
|
"section_break_ajbe",
|
||||||
"paid_amount",
|
"paid_amount",
|
||||||
"amount_due",
|
"amount_due",
|
||||||
"total_amount",
|
"total_amount",
|
||||||
"column_break_quxe",
|
"column_break_quxe",
|
||||||
"section_break_olmx",
|
"section_break_olmx",
|
||||||
"service_address",
|
"service_address",
|
||||||
"site_code",
|
"site_code",
|
||||||
"street",
|
"street",
|
||||||
"city",
|
"city",
|
||||||
"state",
|
"state",
|
||||||
"zip_code",
|
"zip_code",
|
||||||
"column_break_hvmc",
|
"column_break_hvmc",
|
||||||
"notes"
|
"notes"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"fieldname": "supplier",
|
"fieldname": "supplier",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Supplier",
|
"label": "Supplier",
|
||||||
"options": "Supplier"
|
"options": "Supplier"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "supplier_invoice_number",
|
"fieldname": "supplier_invoice_number",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Supplier Invoice Number",
|
"label": "Supplier Invoice Number",
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"unique": 1
|
"unique": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "Due On Receipt",
|
"default": "Due On Receipt",
|
||||||
"fieldname": "invoice_terms",
|
"fieldname": "invoice_terms",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Invoice Terms",
|
"label": "Invoice Terms",
|
||||||
"options": "NET 10\nNET 15\nNET 30\nNET 45\nNET 60\nDue On Receipt",
|
"options": "NET 10\nNET 15\nNET 30\nNET 45\nNET 60\nDue On Receipt",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_yjtl",
|
"fieldname": "column_break_yjtl",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "section_break_swkm",
|
"fieldname": "section_break_swkm",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "supplier_invoice_items",
|
"fieldname": "supplier_invoice_items",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Invoice Items",
|
"label": "Invoice Items",
|
||||||
"options": "Supplier Invoice Items"
|
"options": "Supplier Invoice Items"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "Unpaid",
|
"default": "Unpaid",
|
||||||
"fieldname": "status",
|
"fieldname": "status",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Status",
|
"label": "Status",
|
||||||
"options": "Paid\nUnpaid\nOverdue\nPartially Paid\nPartially Paid and Overdue"
|
"options": "Paid\nUnpaid\nOverdue\nPartially Paid\nPartially Paid and Overdue"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "service_date",
|
"fieldname": "service_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Service Date",
|
"label": "Service Date",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "section_break_olmx",
|
"fieldname": "section_break_olmx",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "notes",
|
"fieldname": "notes",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"label": "Notes"
|
"label": "Notes"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "supplier.company_name",
|
"fetch_from": "supplier.company_name",
|
||||||
"fieldname": "supplier_name",
|
"fieldname": "supplier_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Supplier Name",
|
"label": "Supplier Name",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "service_address",
|
"fieldname": "service_address",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Service Address"
|
"label": "Service Address"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "section_break_ajbe",
|
"fieldname": "section_break_ajbe",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "total_amount",
|
"fieldname": "total_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Total Amount",
|
"label": "Total Amount",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_quxe",
|
"fieldname": "column_break_quxe",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "street",
|
"fieldname": "street",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Street"
|
"label": "Street"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "city",
|
"fieldname": "city",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "City"
|
"label": "City"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "state",
|
"fieldname": "state",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "State"
|
"label": "State"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "zip_code",
|
"fieldname": "zip_code",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Zip Code"
|
"label": "Zip Code"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_hvmc",
|
"fieldname": "column_break_hvmc",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "invoice_date",
|
"fieldname": "invoice_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Invoice Date",
|
"label": "Invoice Date",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "due_date",
|
"fieldname": "due_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Due Date"
|
"label": "Due Date"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "site_code",
|
"fieldname": "site_code",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Site Code"
|
"label": "Site Code"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "section_break_slsq",
|
"fieldname": "section_break_slsq",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "payment_references",
|
"fieldname": "payment_references",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Payment References",
|
"label": "Payment References",
|
||||||
"options": "Invoice Payment References"
|
"options": "Invoice Payment References"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "paid_amount",
|
"fieldname": "paid_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Paid Amount",
|
"label": "Paid Amount",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "amount_due",
|
"fieldname": "amount_due",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Amount Due",
|
"label": "Amount Due",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-10-12 08:12:37.273898",
|
"modified": "2024-10-12 08:12:37.273898",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Suppliers Portal",
|
"module": "Suppliers Portal",
|
||||||
"name": "Invoices",
|
"name": "Invoices",
|
||||||
"naming_rule": "By fieldname",
|
"naming_rule": "By fieldname",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "System Manager",
|
"role": "System Manager",
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort_field": "creation",
|
"sort_field": "creation",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"states": []
|
"states": []
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,84 +7,84 @@ from frappe.utils import add_days, flt, getdate, nowdate
|
||||||
|
|
||||||
|
|
||||||
class Invoices(Document):
|
class Invoices(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.set_due_date()
|
self.set_due_date()
|
||||||
self.set_total_amount()
|
self.set_total_amount()
|
||||||
self.set_total_paid()
|
self.set_total_paid()
|
||||||
self.update_amount_due()
|
self.update_amount_due()
|
||||||
self.update_status()
|
self.update_status()
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
self.update_suppliers_invoice()
|
self.update_suppliers_invoice()
|
||||||
|
|
||||||
def set_total_amount(self):
|
def set_total_amount(self):
|
||||||
if self.get("supplier_invoice_items"):
|
if self.get("supplier_invoice_items"):
|
||||||
total_amount = 0
|
total_amount = 0
|
||||||
for item in self.get("supplier_invoice_items"):
|
for item in self.get("supplier_invoice_items"):
|
||||||
item.amount = flt(item.rate) * flt(item.quantity)
|
item.amount = flt(item.rate) * flt(item.quantity)
|
||||||
total_amount += item.amount
|
total_amount += item.amount
|
||||||
self.db_set("total_amount", total_amount)
|
self.db_set("total_amount", total_amount)
|
||||||
|
|
||||||
def set_due_date(self):
|
def set_due_date(self):
|
||||||
if self.invoice_terms:
|
if self.invoice_terms:
|
||||||
if self.invoice_terms == "NET 10":
|
if self.invoice_terms == "NET 10":
|
||||||
self.due_date = add_days(self.invoice_date, 10)
|
self.due_date = add_days(self.invoice_date, 10)
|
||||||
elif self.invoice_terms == "NET 15":
|
elif self.invoice_terms == "NET 15":
|
||||||
self.due_date = add_days(self.invoice_date, 15)
|
self.due_date = add_days(self.invoice_date, 15)
|
||||||
elif self.invoice_terms == "NET 30":
|
elif self.invoice_terms == "NET 30":
|
||||||
self.due_date = add_days(self.invoice_date, 30)
|
self.due_date = add_days(self.invoice_date, 30)
|
||||||
elif self.invoice_terms == "NET 45":
|
elif self.invoice_terms == "NET 45":
|
||||||
self.due_date = add_days(self.invoice_date, 45)
|
self.due_date = add_days(self.invoice_date, 45)
|
||||||
elif self.invoice_terms == "NET 60":
|
elif self.invoice_terms == "NET 60":
|
||||||
self.due_date = add_days(self.invoice_date, 60)
|
self.due_date = add_days(self.invoice_date, 60)
|
||||||
|
|
||||||
def set_total_paid(self):
|
def set_total_paid(self):
|
||||||
total_paid = 0
|
total_paid = 0
|
||||||
for item in self.payment_references:
|
for item in self.payment_references:
|
||||||
total_paid += item.paid_amount
|
total_paid += item.paid_amount
|
||||||
self.db_set("paid_amount", total_paid)
|
self.db_set("paid_amount", total_paid)
|
||||||
|
|
||||||
def update_status(self):
|
def update_status(self):
|
||||||
if self.paid_amount == 0:
|
if self.paid_amount == 0:
|
||||||
self.status = "Unpaid"
|
self.status = "Unpaid"
|
||||||
elif self.paid_amount < self.total_amount and self.paid_amount > 0:
|
elif self.paid_amount < self.total_amount and self.paid_amount > 0:
|
||||||
self.status = "Partially Paid"
|
self.status = "Partially Paid"
|
||||||
elif self.paid_amount == self.total_amount:
|
elif self.paid_amount == self.total_amount:
|
||||||
self.status = "Paid"
|
self.status = "Paid"
|
||||||
|
|
||||||
if getdate(nowdate()) > getdate(self.due_date):
|
if getdate(nowdate()) > getdate(self.due_date):
|
||||||
if self.paid_amount == 0:
|
if self.paid_amount == 0:
|
||||||
self.status = "Overdue"
|
self.status = "Overdue"
|
||||||
elif self.paid_amount < self.total_amount:
|
elif self.paid_amount < self.total_amount:
|
||||||
self.status = "Partially Paid and Overdue"
|
self.status = "Partially Paid and Overdue"
|
||||||
|
|
||||||
self.db_set("status", self.status, update_modified=False, commit=True)
|
self.db_set("status", self.status, update_modified=False, commit=True)
|
||||||
|
|
||||||
def update_amount_due(self):
|
def update_amount_due(self):
|
||||||
self.db_set(
|
self.db_set(
|
||||||
"amount_due",
|
"amount_due",
|
||||||
flt(self.total_amount) - flt(self.paid_amount),
|
flt(self.total_amount) - flt(self.paid_amount),
|
||||||
update_modified=False,
|
update_modified=False,
|
||||||
commit=True,
|
commit=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
def update_suppliers_invoice(self):
|
def update_suppliers_invoice(self):
|
||||||
supplier = frappe.get_doc("Supplier", self.supplier)
|
supplier = frappe.get_doc("Supplier", self.supplier)
|
||||||
|
|
||||||
# check if invoice already exists
|
# check if invoice already exists
|
||||||
for invoice in supplier.invoices:
|
for invoice in supplier.invoices:
|
||||||
if invoice.invoice_number == self.name:
|
if invoice.invoice_number == self.name:
|
||||||
if invoice.total_due != self.total_amount:
|
if invoice.total_due != self.total_amount:
|
||||||
invoice.total_amount = self.total_amount
|
invoice.total_amount = self.total_amount
|
||||||
if invoice.invoice_date != self.invoice_date:
|
if invoice.invoice_date != self.invoice_date:
|
||||||
invoice.invoice_date = self.invoice_date
|
invoice.invoice_date = self.invoice_date
|
||||||
if invoice.status != self.status:
|
if invoice.status != self.status:
|
||||||
invoice.status = self.status
|
invoice.status = self.status
|
||||||
supplier.save()
|
supplier.save()
|
||||||
return
|
return
|
||||||
|
|
||||||
supplier.append(
|
supplier.append(
|
||||||
"invoices",
|
"invoices",
|
||||||
{"invoice_number": self.name},
|
{"invoice_number": self.name},
|
||||||
)
|
)
|
||||||
supplier.save()
|
supplier.save()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
frappe.listview_settings['Invoices'] = {
|
frappe.listview_settings['Invoices'] = {
|
||||||
before_render() {
|
before_render() {
|
||||||
$('button[data-label="Add Invoices"]>span>span').html('Add Invoice')
|
$('button[data-label="Add Invoices"]>span>span').html('Add Invoice')
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,56 +1,50 @@
|
||||||
{
|
{
|
||||||
"actions": [],
|
"actions": [],
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"creation": "2024-09-24 02:47:44.354811",
|
"creation": "2024-09-24 02:47:44.354811",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": ["service_type", "column_break_ocxt", "quantity", "rate", "amount"],
|
||||||
"service_type",
|
"fields": [
|
||||||
"column_break_ocxt",
|
{
|
||||||
"quantity",
|
"fieldname": "service_type",
|
||||||
"rate",
|
"fieldtype": "Select",
|
||||||
"amount"
|
"label": "Service Type",
|
||||||
],
|
"options": "Repair\nPreventive Maintence"
|
||||||
"fields": [
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "service_type",
|
"fieldname": "column_break_ocxt",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Column Break"
|
||||||
"label": "Service Type",
|
},
|
||||||
"options": "Repair\nPreventive Maintence"
|
{
|
||||||
},
|
"default": "1",
|
||||||
{
|
"fieldname": "quantity",
|
||||||
"fieldname": "column_break_ocxt",
|
"fieldtype": "Float",
|
||||||
"fieldtype": "Column Break"
|
"label": "Quantity"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "1",
|
"fieldname": "rate",
|
||||||
"fieldname": "quantity",
|
"fieldtype": "Currency",
|
||||||
"fieldtype": "Float",
|
"label": "Rate"
|
||||||
"label": "Quantity"
|
},
|
||||||
},
|
{
|
||||||
{
|
"fieldname": "amount",
|
||||||
"fieldname": "rate",
|
"fieldtype": "Currency",
|
||||||
"fieldtype": "Currency",
|
"label": "Amount",
|
||||||
"label": "Rate"
|
"read_only": 1
|
||||||
},
|
}
|
||||||
{
|
],
|
||||||
"fieldname": "amount",
|
"index_web_pages_for_search": 1,
|
||||||
"fieldtype": "Currency",
|
"istable": 1,
|
||||||
"label": "Amount",
|
"links": [],
|
||||||
"read_only": 1
|
"modified": "2024-09-28 00:59:33.037008",
|
||||||
}
|
"modified_by": "Administrator",
|
||||||
],
|
"module": "Suppliers Portal",
|
||||||
"index_web_pages_for_search": 1,
|
"name": "Supplier Invoice Items",
|
||||||
"istable": 1,
|
"owner": "Administrator",
|
||||||
"links": [],
|
"permissions": [],
|
||||||
"modified": "2024-09-28 00:59:33.037008",
|
"sort_field": "creation",
|
||||||
"modified_by": "Administrator",
|
"sort_order": "DESC",
|
||||||
"module": "Suppliers Portal",
|
"states": []
|
||||||
"name": "Supplier Invoice Items",
|
}
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [],
|
|
||||||
"sort_field": "creation",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"states": []
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,69 +1,62 @@
|
||||||
{
|
{
|
||||||
"actions": [],
|
"actions": [],
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"creation": "2024-10-09 16:59:58.079331",
|
"creation": "2024-10-09 16:59:58.079331",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": ["invoice_number", "status", "column_break_mprs", "invoice_date", "terms", "total_due"],
|
||||||
"invoice_number",
|
"fields": [
|
||||||
"status",
|
{
|
||||||
"column_break_mprs",
|
"fieldname": "invoice_number",
|
||||||
"invoice_date",
|
"fieldtype": "Link",
|
||||||
"terms",
|
"label": "Invoice Number",
|
||||||
"total_due"
|
"options": "Invoices",
|
||||||
],
|
"read_only": 1
|
||||||
"fields": [
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "invoice_number",
|
"fetch_from": "invoice_number.invoice_date",
|
||||||
"fieldtype": "Link",
|
"fieldname": "invoice_date",
|
||||||
"label": "Invoice Number",
|
"fieldtype": "Date",
|
||||||
"options": "Invoices",
|
"label": "Invoice Date",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "invoice_number.invoice_date",
|
"fetch_from": "invoice_number.invoice_terms",
|
||||||
"fieldname": "invoice_date",
|
"fieldname": "terms",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Data",
|
||||||
"label": "Invoice Date",
|
"label": "Term",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "invoice_number.invoice_terms",
|
"fetch_from": "invoice_number.total_amount",
|
||||||
"fieldname": "terms",
|
"fieldname": "total_due",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Currency",
|
||||||
"label": "Term",
|
"label": "Total Due",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "invoice_number.total_amount",
|
"fetch_from": "invoice_number.status",
|
||||||
"fieldname": "total_due",
|
"fieldname": "status",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Data",
|
||||||
"label": "Total Due",
|
"label": "Status",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "invoice_number.status",
|
"fieldname": "column_break_mprs",
|
||||||
"fieldname": "status",
|
"fieldtype": "Column Break"
|
||||||
"fieldtype": "Data",
|
}
|
||||||
"label": "Status",
|
],
|
||||||
"read_only": 1
|
"index_web_pages_for_search": 1,
|
||||||
},
|
"istable": 1,
|
||||||
{
|
"links": [],
|
||||||
"fieldname": "column_break_mprs",
|
"modified": "2024-10-09 17:33:59.785852",
|
||||||
"fieldtype": "Column Break"
|
"modified_by": "Administrator",
|
||||||
}
|
"module": "Suppliers Portal",
|
||||||
],
|
"name": "Supplier Invoices",
|
||||||
"index_web_pages_for_search": 1,
|
"owner": "Administrator",
|
||||||
"istable": 1,
|
"permissions": [],
|
||||||
"links": [],
|
"sort_field": "creation",
|
||||||
"modified": "2024-10-09 17:33:59.785852",
|
"sort_order": "DESC",
|
||||||
"modified_by": "Administrator",
|
"states": []
|
||||||
"module": "Suppliers Portal",
|
}
|
||||||
"name": "Supplier Invoices",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [],
|
|
||||||
"sort_field": "creation",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"states": []
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,30 @@
|
||||||
frappe.query_reports["Supplier Invoices"] = {
|
frappe.query_reports['Supplier Invoices'] = {
|
||||||
"filters": [
|
filters: [
|
||||||
{
|
{
|
||||||
"fieldname": "invoice_date_from",
|
fieldname: 'invoice_date_from',
|
||||||
"label": __("Invoice Date From"),
|
label: __('Invoice Date From'),
|
||||||
"fieldtype": "Date",
|
fieldtype: 'Date',
|
||||||
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1), // Default to last month
|
default: frappe.datetime.add_months(frappe.datetime.get_today(), -1), // Default to last month
|
||||||
"placeholder": __("Invoice Date From")
|
placeholder: __('Invoice Date From'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "invoice_date_to",
|
fieldname: 'invoice_date_to',
|
||||||
"label": __("Invoice Date To"),
|
label: __('Invoice Date To'),
|
||||||
"fieldtype": "Date",
|
fieldtype: 'Date',
|
||||||
"default": frappe.datetime.get_today(), // Default to today
|
default: frappe.datetime.get_today(), // Default to today
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "supplier",
|
fieldname: 'supplier',
|
||||||
"label": __("Supplier"),
|
label: __('Supplier'),
|
||||||
"fieldtype": "Link",
|
fieldtype: 'Link',
|
||||||
"options": "Supplier"
|
options: 'Supplier',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "status",
|
fieldname: 'status',
|
||||||
"label": __("Status"),
|
label: __('Status'),
|
||||||
"fieldtype": "Select",
|
fieldtype: 'Select',
|
||||||
"options": "All\nPaid\nUnpaid\nOverdue",
|
options: 'All\nPaid\nUnpaid\nOverdue',
|
||||||
"default": "All",
|
default: 'All',
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
};
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,30 @@
|
||||||
{
|
{
|
||||||
"add_total_row": 1,
|
"add_total_row": 1,
|
||||||
"columns": [],
|
"columns": [],
|
||||||
"creation": "2024-10-09 15:22:34.256149",
|
"creation": "2024-10-09 15:22:34.256149",
|
||||||
"disabled": 1,
|
"disabled": 1,
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Report",
|
"doctype": "Report",
|
||||||
"filters": [],
|
"filters": [],
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": "Yes",
|
"is_standard": "Yes",
|
||||||
"letterhead": null,
|
"letterhead": null,
|
||||||
"modified": "2024-10-09 17:03:58.993246",
|
"modified": "2024-10-09 17:03:58.993246",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Suppliers Portal",
|
"module": "Suppliers Portal",
|
||||||
"name": "Supplier Invoices",
|
"name": "Supplier Invoices",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"prepared_report": 0,
|
"prepared_report": 0,
|
||||||
"ref_doctype": "Invoices",
|
"ref_doctype": "Invoices",
|
||||||
"report_name": "Supplier Invoices",
|
"report_name": "Supplier Invoices",
|
||||||
"report_type": "Script Report",
|
"report_type": "Script Report",
|
||||||
"roles": [
|
"roles": [
|
||||||
{
|
{
|
||||||
"role": "System Manager"
|
"role": "System Manager"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"role": "Portal Supplier"
|
"role": "Portal Supplier"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"timeout": 0
|
"timeout": 0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,37 +2,37 @@ import frappe
|
||||||
|
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
columns = [
|
columns = [
|
||||||
{
|
{
|
||||||
"fieldname": "invoice_number",
|
"fieldname": "invoice_number",
|
||||||
"label": "Invoice Number",
|
"label": "Invoice Number",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Invoices",
|
"options": "Invoices",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "supplier_name",
|
"fieldname": "supplier_name",
|
||||||
"label": "Supplier Name",
|
"label": "Supplier Name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"width": 200,
|
"width": 200,
|
||||||
},
|
},
|
||||||
{"fieldname": "status", "label": "Status", "fieldtype": "Data", "width": 100},
|
{"fieldname": "status", "label": "Status", "fieldtype": "Data", "width": 100},
|
||||||
{"fieldname": "invoice_date", "label": "Invoice Date", "fieldtype": "Date"},
|
{"fieldname": "invoice_date", "label": "Invoice Date", "fieldtype": "Date"},
|
||||||
{"fieldname": "due_date", "label": "Due Date", "fieldtype": "Date"},
|
{"fieldname": "due_date", "label": "Due Date", "fieldtype": "Date"},
|
||||||
{"fieldname": "total_amount", "label": "Total Amount", "fieldtype": "Currency"},
|
{"fieldname": "total_amount", "label": "Total Amount", "fieldtype": "Currency"},
|
||||||
]
|
]
|
||||||
|
|
||||||
conditions = ""
|
conditions = ""
|
||||||
if filters.get("invoice_date_from"):
|
if filters.get("invoice_date_from"):
|
||||||
conditions += " AND invoice_date >= %(invoice_date_from)s"
|
conditions += " AND invoice_date >= %(invoice_date_from)s"
|
||||||
if filters.get("invoice_date_to"):
|
if filters.get("invoice_date_to"):
|
||||||
conditions += " AND invoice_date <= %(invoice_date_to)s"
|
conditions += " AND invoice_date <= %(invoice_date_to)s"
|
||||||
if filters.get("supplier"):
|
if filters.get("supplier"):
|
||||||
conditions += " AND supplier = %(supplier)s"
|
conditions += " AND supplier = %(supplier)s"
|
||||||
if filters.get("status"):
|
if filters.get("status"):
|
||||||
if not filters.get("status") == "All":
|
if not filters.get("status") == "All":
|
||||||
conditions += " AND status = %(status)s"
|
conditions += " AND status = %(status)s"
|
||||||
|
|
||||||
query = f"""
|
query = f"""
|
||||||
SELECT
|
SELECT
|
||||||
name as invoice_number,
|
name as invoice_number,
|
||||||
supplier_name,
|
supplier_name,
|
||||||
|
|
@ -45,5 +45,5 @@ def execute(filters=None):
|
||||||
WHERE
|
WHERE
|
||||||
docstatus = 0 {conditions}
|
docstatus = 0 {conditions}
|
||||||
"""
|
"""
|
||||||
data = frappe.db.sql(query, filters, as_dict=True)
|
data = frappe.db.sql(query, filters, as_dict=True)
|
||||||
return columns, data
|
return columns, data
|
||||||
|
|
|
||||||
|
|
@ -1,63 +1,63 @@
|
||||||
{
|
{
|
||||||
"app": "supplier_portal",
|
"app": "supplier_portal",
|
||||||
"charts": [],
|
"charts": [],
|
||||||
"content": "[{\"id\":\"AyiOTTupgl\",\"type\":\"paragraph\",\"data\":{\"text\":\"Documents\",\"col\":12}},{\"id\":\"64VHemT3p8\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Suppliers\",\"col\":4}},{\"id\":\"_vl927eRbo\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Invoices\",\"col\":4}},{\"id\":\"j428xL5Lje\",\"type\":\"paragraph\",\"data\":{\"text\":\"Reports\",\"col\":12}},{\"id\":\"CDzGMPClRq\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Supplier Invoices Report\",\"col\":4}}]",
|
"content": "[{\"id\":\"AyiOTTupgl\",\"type\":\"paragraph\",\"data\":{\"text\":\"Documents\",\"col\":12}},{\"id\":\"64VHemT3p8\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Suppliers\",\"col\":4}},{\"id\":\"_vl927eRbo\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Invoices\",\"col\":4}},{\"id\":\"j428xL5Lje\",\"type\":\"paragraph\",\"data\":{\"text\":\"Reports\",\"col\":12}},{\"id\":\"CDzGMPClRq\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Supplier Invoices Report\",\"col\":4}}]",
|
||||||
"creation": "2024-10-02 17:23:06.804441",
|
"creation": "2024-10-02 17:23:06.804441",
|
||||||
"custom_blocks": [],
|
"custom_blocks": [],
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Workspace",
|
"doctype": "Workspace",
|
||||||
"for_user": "",
|
"for_user": "",
|
||||||
"hide_custom": 0,
|
"hide_custom": 0,
|
||||||
"icon": "clipboard",
|
"icon": "clipboard",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"indicator_color": "green",
|
"indicator_color": "green",
|
||||||
"is_hidden": 0,
|
"is_hidden": 0,
|
||||||
"label": "Supplier Portal",
|
"label": "Supplier Portal",
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-10-12 07:25:56.798875",
|
"modified": "2024-10-12 07:25:56.798875",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Suppliers Portal",
|
"module": "Suppliers Portal",
|
||||||
"name": "Supplier Portal",
|
"name": "Supplier Portal",
|
||||||
"number_cards": [],
|
"number_cards": [],
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"parent_page": "",
|
"parent_page": "",
|
||||||
"public": 1,
|
"public": 1,
|
||||||
"quick_lists": [],
|
"quick_lists": [],
|
||||||
"restrict_to_domain": "",
|
"restrict_to_domain": "",
|
||||||
"roles": [
|
"roles": [
|
||||||
{
|
{
|
||||||
"role": "Portal Supplier"
|
"role": "Portal Supplier"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"role": "Portal User"
|
"role": "Portal User"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sequence_id": 2.0,
|
"sequence_id": 2.0,
|
||||||
"shortcuts": [
|
"shortcuts": [
|
||||||
{
|
{
|
||||||
"color": "Grey",
|
"color": "Grey",
|
||||||
"doc_view": "List",
|
"doc_view": "List",
|
||||||
"label": "Supplier Invoices Report",
|
"label": "Supplier Invoices Report",
|
||||||
"link_to": "Supplier Invoices",
|
"link_to": "Supplier Invoices",
|
||||||
"type": "Report"
|
"type": "Report"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": "Grey",
|
"color": "Grey",
|
||||||
"doc_view": "List",
|
"doc_view": "List",
|
||||||
"label": "Suppliers",
|
"label": "Suppliers",
|
||||||
"link_to": "Supplier",
|
"link_to": "Supplier",
|
||||||
"stats_filter": "[]",
|
"stats_filter": "[]",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": "Grey",
|
"color": "Grey",
|
||||||
"doc_view": "List",
|
"doc_view": "List",
|
||||||
"label": "Invoices",
|
"label": "Invoices",
|
||||||
"link_to": "Invoices",
|
"link_to": "Invoices",
|
||||||
"stats_filter": "[]",
|
"stats_filter": "[]",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"title": "Supplier Portal",
|
"title": "Supplier Portal",
|
||||||
"type": "Workspace"
|
"type": "Workspace"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,48 +1,48 @@
|
||||||
{
|
{
|
||||||
"app": "Suppliers Portal",
|
"app": "Suppliers Portal",
|
||||||
"charts": [],
|
"charts": [],
|
||||||
"content": "[{\"id\":\"Lix3qbsE_H\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\">Suppliers Portal</span>\",\"col\":12}},{\"id\":\"OdX-YH0tro\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Supplier\",\"col\":4}},{\"id\":\"_vl927eRbo\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Invoices\",\"col\":4}}]",
|
"content": "[{\"id\":\"Lix3qbsE_H\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\">Suppliers Portal</span>\",\"col\":12}},{\"id\":\"OdX-YH0tro\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Supplier\",\"col\":4}},{\"id\":\"_vl927eRbo\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Invoices\",\"col\":4}}]",
|
||||||
"creation": "2024-10-02 17:23:06.804441",
|
"creation": "2024-10-02 17:23:06.804441",
|
||||||
"custom_blocks": [],
|
"custom_blocks": [],
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Workspace",
|
"doctype": "Workspace",
|
||||||
"for_user": "",
|
"for_user": "",
|
||||||
"hide_custom": 0,
|
"hide_custom": 0,
|
||||||
"icon": "clipboard",
|
"icon": "clipboard",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"indicator_color": "green",
|
"indicator_color": "green",
|
||||||
"is_hidden": 0,
|
"is_hidden": 0,
|
||||||
"label": "Suppliers Portal",
|
"label": "Suppliers Portal",
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-10-03 03:19:57.683322",
|
"modified": "2024-10-03 03:19:57.683322",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Suppliers Portal",
|
"module": "Suppliers Portal",
|
||||||
"name": "Suppliers Portal",
|
"name": "Suppliers Portal",
|
||||||
"number_cards": [],
|
"number_cards": [],
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"parent_page": "",
|
"parent_page": "",
|
||||||
"public": 1,
|
"public": 1,
|
||||||
"quick_lists": [],
|
"quick_lists": [],
|
||||||
"roles": [],
|
"roles": [],
|
||||||
"sequence_id": 23.0,
|
"sequence_id": 23.0,
|
||||||
"shortcuts": [
|
"shortcuts": [
|
||||||
{
|
{
|
||||||
"color": "Grey",
|
"color": "Grey",
|
||||||
"doc_view": "List",
|
"doc_view": "List",
|
||||||
"label": "Supplier",
|
"label": "Supplier",
|
||||||
"link_to": "Supplier",
|
"link_to": "Supplier",
|
||||||
"stats_filter": "[]",
|
"stats_filter": "[]",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": "Grey",
|
"color": "Grey",
|
||||||
"doc_view": "List",
|
"doc_view": "List",
|
||||||
"label": "Invoices",
|
"label": "Invoices",
|
||||||
"link_to": "Invoices",
|
"link_to": "Invoices",
|
||||||
"stats_filter": "[]",
|
"stats_filter": "[]",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"title": "Suppliers Portal",
|
"title": "Suppliers Portal",
|
||||||
"type": "Workspace"
|
"type": "Workspace"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,13 @@ import frappe
|
||||||
|
|
||||||
|
|
||||||
def daily_invoice_status_update():
|
def daily_invoice_status_update():
|
||||||
invoices = frappe.get_all(
|
invoices = frappe.get_all(
|
||||||
"Invoices",
|
"Invoices",
|
||||||
filters={
|
filters={"status": ["in", ["Unpaid", "Partially Paid", "Partially Paid and Overdue"]]},
|
||||||
"status": ["in", ["Unpaid", "Partially Paid", "Partially Paid and Overdue"]]
|
fields=["name"],
|
||||||
},
|
)
|
||||||
fields=["name"],
|
for invoice in invoices:
|
||||||
)
|
invoice_doc = frappe.get_doc("Invoices", invoice.name)
|
||||||
for invoice in invoices:
|
invoice_doc.update_status()
|
||||||
invoice_doc = frappe.get_doc("Invoices", invoice.name)
|
invoice_doc.save()
|
||||||
invoice_doc.update_status()
|
frappe.db.commit()
|
||||||
invoice_doc.save()
|
|
||||||
frappe.db.commit()
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,6 @@
|
||||||
<div id="popovers"></div>
|
<div id="popovers"></div>
|
||||||
|
|
||||||
<script> window.csrf_token = '{{ csrf_token }}'; </script>
|
<script> window.csrf_token = '{{ csrf_token }}'; </script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue