Compare commits
17 Commits
c366a55c15
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3aec07892c | ||
|
|
4c6ff6e148 | ||
|
|
cfb1d44b8c | ||
|
|
6f91d97dcd | ||
|
|
741ffe386c | ||
|
|
e5db59403d | ||
|
|
4652fea8fc | ||
|
|
fad2e1c0a8 | ||
| 206b4a5c6a | |||
| 71d0592778 | |||
|
|
f059f5cca1 | ||
|
|
bbb5d68af1 | ||
|
|
4f5e2e5944 | ||
| d76c18614d | |||
|
|
9ddfc33514 | ||
| e7bc050b2e | |||
|
|
e89895b07b |
10
.claude/settings.local.json
Normal file
10
.claude/settings.local.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"permissions": {
|
||||||
|
"allow": [
|
||||||
|
"Bash(npm create *)",
|
||||||
|
"Bash(npm install *)",
|
||||||
|
"Bash(npm run *)",
|
||||||
|
"Bash(xargs grep *)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
27
.context/agents/README.md
Normal file
27
.context/agents/README.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Agent Handbook
|
||||||
|
|
||||||
|
This directory contains ready-to-customize playbooks for AI agents collaborating on the repository.
|
||||||
|
|
||||||
|
## Available Agents
|
||||||
|
- [Code Reviewer](./code-reviewer.md) — Review code changes for quality, style, and best practices
|
||||||
|
- [Bug Fixer](./bug-fixer.md) — Analyze bug reports and error messages
|
||||||
|
- [Feature Developer](./feature-developer.md) — Implement new features according to specifications
|
||||||
|
- [Refactoring Specialist](./refactoring-specialist.md) — Identify code smells and improvement opportunities
|
||||||
|
- [Test Writer](./test-writer.md) — Write comprehensive unit and integration tests
|
||||||
|
- [Documentation Writer](./documentation-writer.md) — Create clear, comprehensive documentation
|
||||||
|
- [Performance Optimizer](./performance-optimizer.md) — Identify performance bottlenecks
|
||||||
|
- [Security Auditor](./security-auditor.md) — Identify security vulnerabilities
|
||||||
|
- [Frontend Specialist](./frontend-specialist.md) — Design and implement user interfaces
|
||||||
|
- [Architect Specialist](./architect-specialist.md) — Design overall system architecture and patterns
|
||||||
|
- [Devops Specialist](./devops-specialist.md) — Design and maintain CI/CD pipelines
|
||||||
|
|
||||||
|
## How To Use These Playbooks
|
||||||
|
1. Pick the agent that matches your task.
|
||||||
|
2. Enrich the template with project-specific context or links.
|
||||||
|
3. Share the final prompt with your AI assistant.
|
||||||
|
4. Capture learnings in the relevant documentation file so future runs improve.
|
||||||
|
|
||||||
|
## Related Resources
|
||||||
|
- [Documentation Index](../docs/README.md)
|
||||||
|
- [Agent Knowledge Base](../../AGENTS.md)
|
||||||
|
- [Contributor Guidelines](../../CONTRIBUTING.md)
|
||||||
10
.context/agents/architect-specialist.md
Normal file
10
.context/agents/architect-specialist.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: agent
|
||||||
|
name: Architect Specialist
|
||||||
|
description: Design overall system architecture and patterns
|
||||||
|
agentType: architect-specialist
|
||||||
|
phases: [P, R]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/agents/bug-fixer.md
Normal file
10
.context/agents/bug-fixer.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: agent
|
||||||
|
name: Bug Fixer
|
||||||
|
description: Analyze bug reports and error messages
|
||||||
|
agentType: bug-fixer
|
||||||
|
phases: [E, V]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/agents/code-reviewer.md
Normal file
10
.context/agents/code-reviewer.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: agent
|
||||||
|
name: Code Reviewer
|
||||||
|
description: Review code changes for quality, style, and best practices
|
||||||
|
agentType: code-reviewer
|
||||||
|
phases: [R, V]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/agents/devops-specialist.md
Normal file
10
.context/agents/devops-specialist.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: agent
|
||||||
|
name: Devops Specialist
|
||||||
|
description: Design and maintain CI/CD pipelines
|
||||||
|
agentType: devops-specialist
|
||||||
|
phases: [E, C]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/agents/documentation-writer.md
Normal file
10
.context/agents/documentation-writer.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: agent
|
||||||
|
name: Documentation Writer
|
||||||
|
description: Create clear, comprehensive documentation
|
||||||
|
agentType: documentation-writer
|
||||||
|
phases: [P, C]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/agents/feature-developer.md
Normal file
10
.context/agents/feature-developer.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: agent
|
||||||
|
name: Feature Developer
|
||||||
|
description: Implement new features according to specifications
|
||||||
|
agentType: feature-developer
|
||||||
|
phases: [P, E]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/agents/frontend-specialist.md
Normal file
10
.context/agents/frontend-specialist.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: agent
|
||||||
|
name: Frontend Specialist
|
||||||
|
description: Design and implement user interfaces
|
||||||
|
agentType: frontend-specialist
|
||||||
|
phases: [P, E]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/agents/performance-optimizer.md
Normal file
10
.context/agents/performance-optimizer.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: agent
|
||||||
|
name: Performance Optimizer
|
||||||
|
description: Identify performance bottlenecks
|
||||||
|
agentType: performance-optimizer
|
||||||
|
phases: [E, V]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/agents/refactoring-specialist.md
Normal file
10
.context/agents/refactoring-specialist.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: agent
|
||||||
|
name: Refactoring Specialist
|
||||||
|
description: Identify code smells and improvement opportunities
|
||||||
|
agentType: refactoring-specialist
|
||||||
|
phases: [E]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/agents/security-auditor.md
Normal file
10
.context/agents/security-auditor.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: agent
|
||||||
|
name: Security Auditor
|
||||||
|
description: Identify security vulnerabilities
|
||||||
|
agentType: security-auditor
|
||||||
|
phases: [R, V]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/agents/test-writer.md
Normal file
10
.context/agents/test-writer.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: agent
|
||||||
|
name: Test Writer
|
||||||
|
description: Write comprehensive unit and integration tests
|
||||||
|
agentType: test-writer
|
||||||
|
phases: [E, V]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
42
.context/docs/README.md
Normal file
42
.context/docs/README.md
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# Documentation Index
|
||||||
|
|
||||||
|
Welcome to the repository knowledge base. Start with the project overview, then dive into specific guides as needed.
|
||||||
|
|
||||||
|
## Core Guides
|
||||||
|
- [Project Overview](./project-overview.md)
|
||||||
|
- [Architecture Notes](./architecture.md)
|
||||||
|
- [Development Workflow](./development-workflow.md)
|
||||||
|
- [Testing Strategy](./testing-strategy.md)
|
||||||
|
- [Glossary & Domain Concepts](./glossary.md)
|
||||||
|
- [Security & Compliance Notes](./security.md)
|
||||||
|
- [Tooling & Productivity Guide](./tooling.md)
|
||||||
|
|
||||||
|
## Repository Snapshot
|
||||||
|
- `angular.json/`
|
||||||
|
- `browserslist/`
|
||||||
|
- `docker-compose.yml/`
|
||||||
|
- `Dockerfile/`
|
||||||
|
- `e2e/`
|
||||||
|
- `k8s/`
|
||||||
|
- `karma.conf.js/`
|
||||||
|
- `kendo-ui-license.txt/`
|
||||||
|
- `nginx.conf/`
|
||||||
|
- `package-lock.json/`
|
||||||
|
- `package.json/`
|
||||||
|
- `README.md/`
|
||||||
|
- `src/` — TypeScript source files and CLI entrypoints.
|
||||||
|
- `tsconfig.app.json/`
|
||||||
|
- `tsconfig.json/`
|
||||||
|
- `tsconfig.spec.json/`
|
||||||
|
- `tslint.json/`
|
||||||
|
|
||||||
|
## Document Map
|
||||||
|
| Guide | File | Primary Inputs |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Project Overview | `project-overview.md` | Roadmap, README, stakeholder notes |
|
||||||
|
| Architecture Notes | `architecture.md` | ADRs, service boundaries, dependency graphs |
|
||||||
|
| Development Workflow | `development-workflow.md` | Branching rules, CI config, contributing guide |
|
||||||
|
| Testing Strategy | `testing-strategy.md` | Test configs, CI gates, known flaky suites |
|
||||||
|
| Glossary & Domain Concepts | `glossary.md` | Business terminology, user personas, domain rules |
|
||||||
|
| Security & Compliance Notes | `security.md` | Auth model, secrets management, compliance requirements |
|
||||||
|
| Tooling & Productivity Guide | `tooling.md` | CLI scripts, IDE configs, automation workflows |
|
||||||
61
.context/docs/architecture.md
Normal file
61
.context/docs/architecture.md
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
---
|
||||||
|
type: doc
|
||||||
|
name: architecture
|
||||||
|
description: System architecture, layers, patterns, and design decisions
|
||||||
|
category: architecture
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: active
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Architecture Notes
|
||||||
|
|
||||||
|
## System Architecture Overview
|
||||||
|
The system is a modular frontend web application built using Angular. It follows a modular monolith architecture where features are grouped into specific modules such as `Sales`, `Partners`, `Financial`, and `CRM`. The application heavily relies on Redux-pattern state management (likely NgRx) to manage global state such as shopping carts, customer sales, and application data flow. Data is fetched via Angular services which communicate with a backend REST API.
|
||||||
|
|
||||||
|
## Architectural Layers
|
||||||
|
- **Components**: UI elements and pages organized by feature domain (`src/app/sales/`, `src/app/partners/`, `src/app/crm/`).
|
||||||
|
- **Services**: Business logic and API communication layer (`src/app/services/`, `src/app/shared/services/`).
|
||||||
|
- **Store / State Management**: Reducers, actions, and models handling complex state management (`src/app/sales/store/`).
|
||||||
|
- **Models**: TypeScript interfaces and classes defining data structures (`src/app/models/`).
|
||||||
|
- **Shared Utils**: Common messages, loading indicators, and validators (`src/app/shared/`).
|
||||||
|
|
||||||
|
> See [`codebase-map.json`](./codebase-map.json) for complete symbol counts and dependency graphs.
|
||||||
|
|
||||||
|
## Detected Design Patterns
|
||||||
|
| Pattern | Confidence | Locations | Description |
|
||||||
|
|---------|------------|-----------|-------------|
|
||||||
|
| Module | 100% | `src/app/*.module.ts` | Angular feature modules for separation of concerns |
|
||||||
|
| Redux / Store | 95% | `src/app/sales/store/` | State management using Actions, Reducers, and Store |
|
||||||
|
| Dependency Injection | 100% | `src/app/services/` | Angular DI for injecting services into components |
|
||||||
|
| Observable / Reactive | 90% | Services & Store | Heavy use of RxJS Observables for async data flows |
|
||||||
|
|
||||||
|
## Entry Points
|
||||||
|
- [AppModule](file:///d:/desenvolvimento/Simplifique/vendaweb/Vendaweb-portal/src/app/app.module.ts)
|
||||||
|
- [AppComponent](file:///d:/desenvolvimento/Simplifique/vendaweb/Vendaweb-portal/src/app/app.component.ts)
|
||||||
|
|
||||||
|
## Public API
|
||||||
|
| Symbol | Type | Location |
|
||||||
|
|--------|------|----------|
|
||||||
|
| `AppModule` | Class | `src/app/app.module.ts` |
|
||||||
|
| `SalesModule` | Class | `src/app/sales/sales.module.ts` |
|
||||||
|
| `PartnersModule` | Class | `src/app/partners/partners.module.ts` |
|
||||||
|
| `ShoppingReducer` | Function | `src/app/sales/store/reducers/shopping.reducer.ts` |
|
||||||
|
|
||||||
|
## Internal System Boundaries
|
||||||
|
The application is clearly separated into bounded contexts:
|
||||||
|
- **Sales**: Core module handling product listings, shopping carts, checkout, and ordering.
|
||||||
|
- **Partners**: Module for managing partner ranges, reports, and payments.
|
||||||
|
- **CRM**: Module handling customer data, editing, and listing.
|
||||||
|
- **Admin/Auth**: Authentication and user permission management.
|
||||||
|
|
||||||
|
## Top Directories Snapshot
|
||||||
|
- `src/app/sales/` (~50+ files)
|
||||||
|
- `src/app/models/` (~40+ files)
|
||||||
|
- `src/app/shared/` (~30+ files)
|
||||||
|
- `src/app/partners/` (~20+ files)
|
||||||
|
- `src/app/components/` (~10+ files)
|
||||||
|
|
||||||
|
## Related Resources
|
||||||
|
- [Project Overview](./project-overview.md)
|
||||||
|
- [Data Flow](./data-flow.md)
|
||||||
1104
.context/docs/codebase-map.json
Normal file
1104
.context/docs/codebase-map.json
Normal file
File diff suppressed because it is too large
Load Diff
40
.context/docs/development-workflow.md
Normal file
40
.context/docs/development-workflow.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
type: doc
|
||||||
|
name: development-workflow
|
||||||
|
description: Day-to-day engineering processes, branching, and contribution guidelines
|
||||||
|
category: workflow
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: active
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Development Workflow
|
||||||
|
|
||||||
|
## Day-to-Day Process
|
||||||
|
This Angular repository requires developers to implement features within their respective feature modules (e.g., `Sales`, `Partners`, `CRM`). Developers should ensure that all new services, components, and state management changes are properly typed using the `src/app/models` directory.
|
||||||
|
|
||||||
|
## Branching & Releases
|
||||||
|
We follow a standard Git workflow:
|
||||||
|
- `main` / `master`: The stable production branch.
|
||||||
|
- `develop`: The primary integration branch.
|
||||||
|
- Feature branches: Created from `develop` using a standard naming convention like `feat/feature-name` or `bugfix/issue-description`.
|
||||||
|
Commits should follow Conventional Commits (e.g., `feat(sales): add discount module`).
|
||||||
|
|
||||||
|
## Local Development
|
||||||
|
- Install dependencies: `npm install`
|
||||||
|
- Run local development server: `npm start` or `npm run dev` (uses Angular CLI `ng serve`)
|
||||||
|
- Run tests: `npm test`
|
||||||
|
- Build for production: `npm run build`
|
||||||
|
|
||||||
|
## Code Review Expectations
|
||||||
|
- Ensure Angular best practices are followed (e.g., Unsubscribing from Observables, using `OnPush` change detection where applicable).
|
||||||
|
- Avoid mutating state directly in components; use the Store actions.
|
||||||
|
- Keep components small and focused, extracting complex business logic into Services.
|
||||||
|
- All new features should include proper TypeScript models.
|
||||||
|
|
||||||
|
## Onboarding Tasks
|
||||||
|
New developers should begin by reading the `Project Overview` and familiarizing themselves with the `Sales` module, as it is the core of the application.
|
||||||
|
|
||||||
|
## Cross-References
|
||||||
|
- [Testing Strategy](./testing-strategy.md)
|
||||||
|
- [Tooling](./tooling.md)
|
||||||
45
.context/docs/glossary.md
Normal file
45
.context/docs/glossary.md
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
type: doc
|
||||||
|
name: glossary
|
||||||
|
description: Project terminology, type definitions, domain entities, and business rules
|
||||||
|
category: glossary
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: active
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Glossary & Domain Concepts
|
||||||
|
|
||||||
|
## Glossary
|
||||||
|
- **PreOrder (Pré-venda)**: An order created by a seller that has not yet been billed.
|
||||||
|
- **Cart (Carrinho)**: A temporary collection of products a customer intends to purchase.
|
||||||
|
- **Checkout**: The process of finalizing an order, choosing payment methods and installments.
|
||||||
|
- **Seller (Vendedor)**: The user using the application to sell products to customers.
|
||||||
|
- **Partner (Parceiro)**: A B2B entity that works with the company, has specific commission and range logic.
|
||||||
|
- **Tintométrico**: A specific feature related to color mixing, usually for paint products.
|
||||||
|
|
||||||
|
## Type Definitions
|
||||||
|
- `Customer` (src/app/models/customer.model.ts)
|
||||||
|
- `Product` (src/app/models/product.model.ts)
|
||||||
|
- `Order` (src/app/models/order.model.ts)
|
||||||
|
- `PreOrder` (src/app/models/pre-order.model.ts)
|
||||||
|
- `CartModel` (src/app/models/cart.model.ts)
|
||||||
|
- `SaleProduct` (src/app/models/sale-product.model.ts)
|
||||||
|
|
||||||
|
## Enumerations
|
||||||
|
- `ShoppingActionTypes` (src/app/sales/store/actions/shopping.action.ts)
|
||||||
|
- `CustomerSaleActionTypes` (src/app/sales/store/actions/customer-sale.action.ts)
|
||||||
|
|
||||||
|
## Core Terms
|
||||||
|
- **State/Store**: Refers to the application's global Redux state (NgRx) which holds the current customer, cart contents, and authentication status.
|
||||||
|
- **CRM**: Customer Relationship Management section where sellers can view, create, or edit customer profiles.
|
||||||
|
|
||||||
|
## Personas / Actors
|
||||||
|
- **Seller (Vendedor)**: Wants to quickly look up products, add them to a cart, apply discounts, and checkout on behalf of a customer.
|
||||||
|
- **Admin**: Configures permissions, views high-level dashboard KPIs.
|
||||||
|
- **Partner (Parceiro)**: Checks commissions, extracts, and ranges.
|
||||||
|
|
||||||
|
## Domain Rules & Invariants
|
||||||
|
- A cart must be associated with a customer before checkout.
|
||||||
|
- Discounts are governed by specific authorization roles.
|
||||||
|
- The `Tintométrico` module calculates specific prices based on color compositions.
|
||||||
49
.context/docs/project-overview.md
Normal file
49
.context/docs/project-overview.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
---
|
||||||
|
type: doc
|
||||||
|
name: project-overview
|
||||||
|
description: High-level overview of the project, its purpose, and key components
|
||||||
|
category: overview
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: active
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Project Overview
|
||||||
|
This project is an Angular-based B2B/B2C Sales Portal (VendaWeb). It empowers sellers to manage customers, browse product catalogs, assemble carts, and process orders, while also offering CRM, Partner Management, and administrative capabilities.
|
||||||
|
|
||||||
|
> **Detailed Analysis**: For complete symbol counts, architecture layers, and dependency graphs, see [`codebase-map.json`](./codebase-map.json).
|
||||||
|
|
||||||
|
## Quick Facts
|
||||||
|
- **Root**: `/`
|
||||||
|
- **Languages**: TypeScript, HTML, SCSS
|
||||||
|
- **Framework**: Angular
|
||||||
|
- **State Management**: NgRx (Redux pattern)
|
||||||
|
|
||||||
|
## Entry Points
|
||||||
|
- [AppModule](file:///d:/desenvolvimento/Simplifique/vendaweb/Vendaweb-portal/src/app/app.module.ts)
|
||||||
|
- [main.ts](file:///d:/desenvolvimento/Simplifique/vendaweb/Vendaweb-portal/src/main.ts)
|
||||||
|
|
||||||
|
## Key Exports
|
||||||
|
- `AppModule`
|
||||||
|
- `SalesModule`
|
||||||
|
- `PartnersModule`
|
||||||
|
|
||||||
|
## File Structure & Code Organization
|
||||||
|
- `src/app/sales/` — Core point-of-sale functionality (cart, products, checkout).
|
||||||
|
- `src/app/crm/` — Customer management interfaces.
|
||||||
|
- `src/app/partners/` — Partner reporting, commissions, and management.
|
||||||
|
- `src/app/financial/` — Financial operations and checkout.
|
||||||
|
- `src/app/models/` — TypeScript interfaces representing business entities.
|
||||||
|
- `src/app/shared/` — Reusable UI components, interceptors, and services.
|
||||||
|
- `src/app/auth/` — Authentication and login flows.
|
||||||
|
|
||||||
|
## Technology Stack Summary
|
||||||
|
- **Frontend**: Angular
|
||||||
|
- **State**: NgRx Store
|
||||||
|
- **Styling**: SCSS, Kendo UI (`kendo-ui-license.txt` indicates Kendo usage)
|
||||||
|
- **Tooling**: Angular CLI, TypeScript, npm
|
||||||
|
|
||||||
|
## Getting Started Checklist
|
||||||
|
1. Install dependencies with `npm install`.
|
||||||
|
2. Run the application locally with `npm run start` or `ng serve`.
|
||||||
|
3. Navigate to `http://localhost:4200` to view the app.
|
||||||
23
.context/docs/qa/README.md
Normal file
23
.context/docs/qa/README.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Q&A Index
|
||||||
|
|
||||||
|
Project type: **web-app**
|
||||||
|
|
||||||
|
Generated: 2026-04-29T20:15:44.291Z
|
||||||
|
|
||||||
|
## Getting-started
|
||||||
|
|
||||||
|
- [How do I set up and run this project?](./getting-started.md)
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
- [How is the codebase organized?](./project-structure.md)
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- [How does authentication work?](./authentication.md)
|
||||||
|
- [How is data stored and accessed?](./database.md)
|
||||||
|
- [What API endpoints are available?](./api-endpoints.md)
|
||||||
|
|
||||||
|
## Operations
|
||||||
|
|
||||||
|
- [How do I deploy this project?](./deployment.md)
|
||||||
11
.context/docs/qa/api-endpoints.md
Normal file
11
.context/docs/qa/api-endpoints.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
slug: api-endpoints
|
||||||
|
category: features
|
||||||
|
generatedAt: 2026-04-29T20:15:39.516Z
|
||||||
|
---
|
||||||
|
|
||||||
|
# What API endpoints are available?
|
||||||
|
|
||||||
|
## API Endpoints
|
||||||
|
|
||||||
|
### Detected API Files
|
||||||
23
.context/docs/qa/authentication.md
Normal file
23
.context/docs/qa/authentication.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
slug: authentication
|
||||||
|
category: features
|
||||||
|
generatedAt: 2026-04-29T20:15:39.516Z
|
||||||
|
relevantFiles:
|
||||||
|
- C:\Users\luis.estevao\AppData\Local\Programs\Antigravity\src\app\guards\auth.guard.ts
|
||||||
|
- C:\Users\luis.estevao\AppData\Local\Programs\Antigravity\src\app\auth\auth-login\auth-login.component.ts
|
||||||
|
- C:\Users\luis.estevao\AppData\Local\Programs\Antigravity\src\app\auth\auth.module.ts
|
||||||
|
- C:\Users\luis.estevao\AppData\Local\Programs\Antigravity\src\app\auth\services\auth.service.ts
|
||||||
|
- C:\Users\luis.estevao\AppData\Local\Programs\Antigravity\src\app\shared\messages\auth-user\auth-user.component.ts
|
||||||
|
---
|
||||||
|
|
||||||
|
# How does authentication work?
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
### Implementation Details
|
||||||
|
|
||||||
|
- Auth-related symbol: AuthGuard
|
||||||
|
- Auth-related symbol: AuthLoginComponent
|
||||||
|
- Auth-related symbol: AuthModule
|
||||||
|
- Auth-related symbol: AuthService
|
||||||
|
- Auth-related symbol: AuthUserComponent
|
||||||
22
.context/docs/qa/database.md
Normal file
22
.context/docs/qa/database.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
slug: database
|
||||||
|
category: features
|
||||||
|
generatedAt: 2026-04-29T20:15:39.516Z
|
||||||
|
relevantFiles:
|
||||||
|
- C:\Users\luis.estevao\AppData\Local\Programs\Antigravity\src\app\sales\store\models\action.model.ts
|
||||||
|
- C:\Users\luis.estevao\AppData\Local\Programs\Antigravity\src\app\models\cart-itens.model.ts
|
||||||
|
- C:\Users\luis.estevao\AppData\Local\Programs\Antigravity\src\app\models\cart.model.ts
|
||||||
|
- C:\Users\luis.estevao\AppData\Local\Programs\Antigravity\src\app\sales\components\create-customer-modal\create-customer-modal.component.ts
|
||||||
|
---
|
||||||
|
|
||||||
|
# How is data stored and accessed?
|
||||||
|
|
||||||
|
## Database
|
||||||
|
|
||||||
|
### Implementation Details
|
||||||
|
|
||||||
|
- Database-related symbol: ActionModel
|
||||||
|
- Database-related symbol: CartItensModel
|
||||||
|
- Database-related symbol: CartModel
|
||||||
|
- Database-related symbol: JsonModel
|
||||||
|
- Data layer detected in architecture
|
||||||
21
.context/docs/qa/deployment.md
Normal file
21
.context/docs/qa/deployment.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
slug: deployment
|
||||||
|
category: operations
|
||||||
|
generatedAt: 2026-04-29T20:15:44.246Z
|
||||||
|
relevantFiles:
|
||||||
|
- docker-compose.yml
|
||||||
|
- Dockerfile
|
||||||
|
---
|
||||||
|
|
||||||
|
# How do I deploy this project?
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
This project includes Docker configuration.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -t app .
|
||||||
|
docker run -p 3000:3000 app
|
||||||
|
```
|
||||||
32
.context/docs/qa/getting-started.md
Normal file
32
.context/docs/qa/getting-started.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
slug: getting-started
|
||||||
|
category: getting-started
|
||||||
|
generatedAt: 2026-04-29T20:11:48.572Z
|
||||||
|
---
|
||||||
|
|
||||||
|
# How do I set up and run this project?
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Node.js (LTS version recommended)
|
||||||
|
- npm
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone the repository
|
||||||
|
git clone <repository-url>
|
||||||
|
cd Vendaweb-portal
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# See package.json for available scripts
|
||||||
|
npm run <script-name>
|
||||||
|
```
|
||||||
15
.context/docs/qa/project-structure.md
Normal file
15
.context/docs/qa/project-structure.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
slug: project-structure
|
||||||
|
category: architecture
|
||||||
|
generatedAt: 2026-04-29T20:15:39.515Z
|
||||||
|
---
|
||||||
|
|
||||||
|
# How is the codebase organized?
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
e2e/
|
||||||
|
k8s/
|
||||||
|
src/
|
||||||
|
```
|
||||||
25
.context/docs/security.md
Normal file
25
.context/docs/security.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
type: doc
|
||||||
|
name: security
|
||||||
|
description: Security policies, authentication, secrets management, and compliance requirements
|
||||||
|
category: security
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: active
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Security & Compliance Notes
|
||||||
|
|
||||||
|
## Authentication & Authorization
|
||||||
|
The application uses JWT (JSON Web Tokens) for authentication.
|
||||||
|
- The `AuthModule` handles user login (`AuthLoginComponent`).
|
||||||
|
- An `AuthGuard` is implemented to protect specific routes, ensuring that unauthenticated users are redirected to the login page.
|
||||||
|
- Role-based access control (RBAC) is implemented via `PermissionUser` components and specific guards.
|
||||||
|
|
||||||
|
## Secrets & Sensitive Data
|
||||||
|
- Environment variables (`src/environments/`) contain API endpoints.
|
||||||
|
- Avoid hardcoding tokens or sensitive keys directly into the source code.
|
||||||
|
- JWT tokens are stored in `localStorage` or `sessionStorage` and attached to outgoing requests via an HttpInterceptor.
|
||||||
|
|
||||||
|
## Cross-References
|
||||||
|
- [Architecture](./architecture.md)
|
||||||
25
.context/docs/testing-strategy.md
Normal file
25
.context/docs/testing-strategy.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
type: doc
|
||||||
|
name: testing-strategy
|
||||||
|
description: Test frameworks, patterns, coverage requirements, and quality gates
|
||||||
|
category: testing
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: active
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Testing Strategy
|
||||||
|
|
||||||
|
## Test Types
|
||||||
|
- **Unit**: Jasmine and Karma, files named `*.spec.ts`.
|
||||||
|
- **E2E**: Protractor (`e2e/` folder), files named `*.e2e-spec.ts`.
|
||||||
|
|
||||||
|
## Running Tests
|
||||||
|
- All tests: `npm run test` or `ng test`
|
||||||
|
- E2E tests: `npm run e2e` or `ng e2e`
|
||||||
|
- Watch mode: `npm run test -- --watch`
|
||||||
|
|
||||||
|
## Quality Gates
|
||||||
|
- Components should have accompanying `.spec.ts` files ensuring fundamental rendering and interactions.
|
||||||
|
- NgRx reducers and effects must be covered by unit tests.
|
||||||
|
- TypeScript strict typing helps catch compile-time issues before tests even run.
|
||||||
33
.context/docs/tooling.md
Normal file
33
.context/docs/tooling.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
type: doc
|
||||||
|
name: tooling
|
||||||
|
description: Scripts, IDE settings, automation, and developer productivity tips
|
||||||
|
category: tooling
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: active
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Tooling & Productivity Guide
|
||||||
|
|
||||||
|
## Required Tooling
|
||||||
|
- **Node.js**: The JavaScript runtime.
|
||||||
|
- **npm**: Package manager.
|
||||||
|
- **Angular CLI**: Install globally via `npm install -g @angular/cli`.
|
||||||
|
|
||||||
|
## Recommended Automation
|
||||||
|
- Formatting: Prettier/ESLint integration should be configured.
|
||||||
|
- Scaffolding: Use Angular CLI to generate boilerplate.
|
||||||
|
- Generate component: `ng g c component-name`
|
||||||
|
- Generate service: `ng g s service-name`
|
||||||
|
|
||||||
|
## IDE / Editor Setup
|
||||||
|
- **VS Code** is highly recommended.
|
||||||
|
- **Extensions**:
|
||||||
|
- Angular Language Service
|
||||||
|
- ESLint
|
||||||
|
- Prettier
|
||||||
|
- NgRx Snippets
|
||||||
|
|
||||||
|
## Productivity Tips
|
||||||
|
- Utilize the Redux DevTools extension in your browser to debug NgRx state changes in real-time.
|
||||||
73
.context/skills/README.md
Normal file
73
.context/skills/README.md
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
# Skills
|
||||||
|
|
||||||
|
On-demand expertise for AI agents. Skills are task-specific procedures that get activated when relevant.
|
||||||
|
|
||||||
|
> Project: Vendaweb-portal
|
||||||
|
|
||||||
|
## How Skills Work
|
||||||
|
|
||||||
|
1. **Discovery**: AI agents discover available skills
|
||||||
|
2. **Matching**: When a task matches a skill's description, it's activated
|
||||||
|
3. **Execution**: The skill's instructions guide the AI's behavior
|
||||||
|
|
||||||
|
## Available Skills
|
||||||
|
|
||||||
|
### Built-in Skills
|
||||||
|
|
||||||
|
| Skill | Description | Phases |
|
||||||
|
|-------|-------------|--------|
|
||||||
|
| [Commit Message](./commit-message/SKILL.md) | Generate commit messages following conventional commits with scope detection | E, C |
|
||||||
|
| [Pr Review](./pr-review/SKILL.md) | Review pull requests against team standards and best practices | R, V |
|
||||||
|
| [Code Review](./code-review/SKILL.md) | Review code quality, patterns, and best practices | R, V |
|
||||||
|
| [Test Generation](./test-generation/SKILL.md) | Generate comprehensive test cases for code | E, V |
|
||||||
|
| [Documentation](./documentation/SKILL.md) | Generate and update technical documentation | P, C |
|
||||||
|
| [Refactoring](./refactoring/SKILL.md) | Safe code refactoring with step-by-step approach | E |
|
||||||
|
| [Bug Investigation](./bug-investigation/SKILL.md) | Systematic bug investigation and root cause analysis | E, V |
|
||||||
|
| [Feature Breakdown](./feature-breakdown/SKILL.md) | Break down features into implementable tasks | P |
|
||||||
|
| [Api Design](./api-design/SKILL.md) | Design RESTful APIs following best practices | P, R |
|
||||||
|
| [Security Audit](./security-audit/SKILL.md) | Security review checklist for code and infrastructure | R, V |
|
||||||
|
|
||||||
|
## Creating Custom Skills
|
||||||
|
|
||||||
|
Create a new skill by adding a directory with a `SKILL.md` file:
|
||||||
|
|
||||||
|
```
|
||||||
|
.context/skills/
|
||||||
|
└── my-skill/
|
||||||
|
├── SKILL.md # Required: skill definition
|
||||||
|
└── templates/ # Optional: helper resources
|
||||||
|
└── checklist.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### SKILL.md Format
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
name: my-skill
|
||||||
|
description: When to use this skill
|
||||||
|
phases: [P, E, V] # Optional: PREVC phases
|
||||||
|
mode: false # Optional: mode command?
|
||||||
|
---
|
||||||
|
|
||||||
|
# My Skill
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
[Description of when this skill applies]
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
1. Step one
|
||||||
|
2. Step two
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
[Usage examples]
|
||||||
|
```
|
||||||
|
|
||||||
|
## PREVC Phase Mapping
|
||||||
|
|
||||||
|
| Phase | Name | Skills |
|
||||||
|
|-------|------|--------|
|
||||||
|
| P | Planning | feature-breakdown, documentation, api-design |
|
||||||
|
| R | Review | pr-review, code-review, api-design, security-audit |
|
||||||
|
| E | Execution | commit-message, test-generation, refactoring, bug-investigation |
|
||||||
|
| V | Validation | pr-review, code-review, test-generation, security-audit |
|
||||||
|
| C | Confirmation | commit-message, documentation |
|
||||||
10
.context/skills/api-design/SKILL.md
Normal file
10
.context/skills/api-design/SKILL.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: skill
|
||||||
|
name: Api Design
|
||||||
|
description: Design RESTful APIs following best practices
|
||||||
|
skillSlug: api-design
|
||||||
|
phases: [P, R]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/skills/bug-investigation/SKILL.md
Normal file
10
.context/skills/bug-investigation/SKILL.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: skill
|
||||||
|
name: Bug Investigation
|
||||||
|
description: Systematic bug investigation and root cause analysis
|
||||||
|
skillSlug: bug-investigation
|
||||||
|
phases: [E, V]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/skills/code-review/SKILL.md
Normal file
10
.context/skills/code-review/SKILL.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: skill
|
||||||
|
name: Code Review
|
||||||
|
description: Review code quality, patterns, and best practices
|
||||||
|
skillSlug: code-review
|
||||||
|
phases: [R, V]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/skills/commit-message/SKILL.md
Normal file
10
.context/skills/commit-message/SKILL.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: skill
|
||||||
|
name: Commit Message
|
||||||
|
description: Generate commit messages following conventional commits with scope detection
|
||||||
|
skillSlug: commit-message
|
||||||
|
phases: [E, C]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/skills/documentation/SKILL.md
Normal file
10
.context/skills/documentation/SKILL.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: skill
|
||||||
|
name: Documentation
|
||||||
|
description: Generate and update technical documentation
|
||||||
|
skillSlug: documentation
|
||||||
|
phases: [P, C]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/skills/feature-breakdown/SKILL.md
Normal file
10
.context/skills/feature-breakdown/SKILL.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: skill
|
||||||
|
name: Feature Breakdown
|
||||||
|
description: Break down features into implementable tasks
|
||||||
|
skillSlug: feature-breakdown
|
||||||
|
phases: [P]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/skills/pr-review/SKILL.md
Normal file
10
.context/skills/pr-review/SKILL.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: skill
|
||||||
|
name: Pr Review
|
||||||
|
description: Review pull requests against team standards and best practices
|
||||||
|
skillSlug: pr-review
|
||||||
|
phases: [R, V]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/skills/refactoring/SKILL.md
Normal file
10
.context/skills/refactoring/SKILL.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: skill
|
||||||
|
name: Refactoring
|
||||||
|
description: Safe code refactoring with step-by-step approach
|
||||||
|
skillSlug: refactoring
|
||||||
|
phases: [E]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/skills/security-audit/SKILL.md
Normal file
10
.context/skills/security-audit/SKILL.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: skill
|
||||||
|
name: Security Audit
|
||||||
|
description: Security review checklist for code and infrastructure
|
||||||
|
skillSlug: security-audit
|
||||||
|
phases: [R, V]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
10
.context/skills/test-generation/SKILL.md
Normal file
10
.context/skills/test-generation/SKILL.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
type: skill
|
||||||
|
name: Test Generation
|
||||||
|
description: Generate comprehensive test cases for code
|
||||||
|
skillSlug: test-generation
|
||||||
|
phases: [E, V]
|
||||||
|
generated: 2026-04-29
|
||||||
|
status: unfilled
|
||||||
|
scaffoldVersion: "2.0.0"
|
||||||
|
---
|
||||||
4
.context/workflow/actions.jsonl
Normal file
4
.context/workflow/actions.jsonl
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{"timestamp":"2026-04-29T20:15:44.301Z","tool":"context","action":"init","status":"success","details":{"params":{"action":"init","repoPath":"d:\\desenvolvimento\\Simplifique\\vendaweb\\Vendaweb-portal","autoFill":true},"result":{"status":"incomplete"}}}
|
||||||
|
{"timestamp":"2026-04-29T20:17:00.305Z","tool":"context","action":"listToFill","status":"success","details":{"params":{"action":"listToFill","repoPath":"d:\\desenvolvimento\\Simplifique\\vendaweb\\Vendaweb-portal","target":"docs"},"result":{"success":true}}}
|
||||||
|
{"timestamp":"2026-04-29T20:17:21.000Z","tool":"context","action":"fill","status":"success","details":{"params":{"action":"fill","repoPath":"d:\\desenvolvimento\\Simplifique\\vendaweb\\Vendaweb-portal","target":"docs"},"result":{"success":true}}}
|
||||||
|
{"timestamp":"2026-04-29T20:18:01.149Z","tool":"context","action":"fill","status":"success","details":{"params":{"action":"fill","repoPath":"d:\\desenvolvimento\\Simplifique\\vendaweb\\Vendaweb-portal","target":"docs","offset":3,"limit":5},"result":{"success":true}}}
|
||||||
34
AGENTS.md
Normal file
34
AGENTS.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
## Dev environment tips
|
||||||
|
- Install dependencies with `npm install` before running scaffolds.
|
||||||
|
- Use `npm run dev` for the interactive TypeScript session that powers local experimentation.
|
||||||
|
- Run `npm run build` to refresh the CommonJS bundle in `dist/` before shipping changes.
|
||||||
|
- Store generated artefacts in `.context/` so reruns stay deterministic.
|
||||||
|
|
||||||
|
## Testing instructions
|
||||||
|
- Execute `npm run test` to run the Jest suite.
|
||||||
|
- Append `-- --watch` while iterating on a failing spec.
|
||||||
|
- Trigger `npm run build && npm run test` before opening a PR to mimic CI.
|
||||||
|
- Add or update tests alongside any generator or CLI changes.
|
||||||
|
|
||||||
|
## PR instructions
|
||||||
|
- Follow Conventional Commits (for example, `feat(scaffolding): add doc links`).
|
||||||
|
- Cross-link new scaffolds in `docs/README.md` and `agents/README.md` so future agents can find them.
|
||||||
|
- Attach sample CLI output or generated markdown when behaviour shifts.
|
||||||
|
- Confirm the built artefacts in `dist/` match the new source changes.
|
||||||
|
|
||||||
|
## Repository map
|
||||||
|
- `angular.json/` — explain what lives here and when agents should edit it.
|
||||||
|
- `browserslist/` — explain what lives here and when agents should edit it.
|
||||||
|
- `docker-compose.yml/` — explain what lives here and when agents should edit it.
|
||||||
|
- `Dockerfile/` — explain what lives here and when agents should edit it.
|
||||||
|
- `e2e/` — explain what lives here and when agents should edit it.
|
||||||
|
- `k8s/` — explain what lives here and when agents should edit it.
|
||||||
|
- `karma.conf.js/` — explain what lives here and when agents should edit it.
|
||||||
|
- `kendo-ui-license.txt/` — explain what lives here and when agents should edit it.
|
||||||
|
|
||||||
|
## AI Context References
|
||||||
|
- Documentation index: `.context/docs/README.md`
|
||||||
|
- Agent playbooks: `.context/agents/README.md`
|
||||||
|
- Contributor guide: `CONTRIBUTING.md`
|
||||||
@@ -7,4 +7,4 @@ spec:
|
|||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: portal
|
- name: portal
|
||||||
image: 172.35.0.216:3000/simplifique/vendaweb-portal:47945c9
|
image: 172.35.0.216:3000/simplifique/vendaweb-portal:4c6ff6e
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
<app-header-admin></app-header-admin>
|
<app-header-admin></app-header-admin>
|
||||||
<div class="d-flex flex-column wrapper">
|
<div class="d-flex flex-column wrapper">
|
||||||
|
<div class="loading-overlay" *ngIf="(loading$ | async) || (updating$ | async)">
|
||||||
|
<div class="loading-content">
|
||||||
|
<kendo-loader type="converging-spinner" themeColor="primary" size="large"></kendo-loader>
|
||||||
|
<div class="mt-2">Carregando dados do pedido...</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="container cart-container my-4">
|
<div class="container cart-container my-4">
|
||||||
<!-- Primeira Linha -->
|
<!-- Primeira Linha -->
|
||||||
<!-- <div class="row mb-3">
|
<!-- <div class="row mb-3">
|
||||||
@@ -854,7 +860,7 @@
|
|||||||
<span *ngIf="!isLoadingPreOrder" class="text-btn-order">Fechar orçamento</span>
|
<span *ngIf="!isLoadingPreOrder" class="text-btn-order">Fechar orçamento</span>
|
||||||
</button> -->
|
</button> -->
|
||||||
|
|
||||||
<button *ngIf="!isLoadingPreOrder" kendoButton class="btn-order w-100"
|
<button *ngIf="!isLoadingPreOrder" kendoButton class="btn-pre-order w-100"
|
||||||
(click)="showConfirmation()" [disabled]="isLoadingPreOrder" [icon]="loadingIconOrder">
|
(click)="showConfirmation()" [disabled]="isLoadingPreOrder" [icon]="loadingIconOrder">
|
||||||
<span class="text-btn-order">Fechar orçamento</span>
|
<span class="text-btn-order">Fechar orçamento</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -933,7 +939,7 @@
|
|||||||
message="{{ messageConfirmation }}" textButtonConfirmation="{{ textButtonConfirmation }}"
|
message="{{ messageConfirmation }}" textButtonConfirmation="{{ textButtonConfirmation }}"
|
||||||
textButtonCancel="{{ textButtonCancel }}" (resultEvent)="confirmChangePaymentPlan($event)"></app-confirmation>
|
textButtonCancel="{{ textButtonCancel }}" (resultEvent)="confirmChangePaymentPlan($event)"></app-confirmation>
|
||||||
|
|
||||||
<app-discount-item-sales *ngIf="showDiscountItem" opened="showDiscountItem" title="{{ titleMessage }}"
|
<app-discount-item-sales *ngIf="showDiscountItem" opened="showDiscountItem" title="Desconto por Item"
|
||||||
textButtonConfirmation="{{ textButtonConfirmation }}" textButtonCancel="{{ textButtonCancel }}"
|
textButtonConfirmation="{{ textButtonConfirmation }}" textButtonCancel="{{ textButtonCancel }}"
|
||||||
[shoppingItem]="itemSelect" (resultEvent)="returnDiscountItem($event)"></app-discount-item-sales>
|
[shoppingItem]="itemSelect" (resultEvent)="returnDiscountItem($event)"></app-discount-item-sales>
|
||||||
|
|
||||||
|
|||||||
@@ -991,6 +991,26 @@ kendo-treeview:hover {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loading-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: rgba(255, 255, 255, 0.7);
|
||||||
|
z-index: 9999;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-content {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #2d2e83;
|
||||||
|
}
|
||||||
|
|
||||||
/* Responsividade para desktops maiores (largura > 1200px) */
|
/* Responsividade para desktops maiores (largura > 1200px) */
|
||||||
@media (min-width: 1200px) {
|
@media (min-width: 1200px) {
|
||||||
.card-resume {
|
.card-resume {
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ export class CartSalesComponent
|
|||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
this.loadShopping();
|
//this.loadShopping();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit(): void { }
|
ngAfterViewInit(): void { }
|
||||||
@@ -326,18 +326,9 @@ export class CartSalesComponent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadShopping() {
|
|
||||||
this.shoppingSubscription = this.shopping$.subscribe((data) => {
|
|
||||||
this.shopping = data;
|
|
||||||
if (this.shopping !== null) {
|
|
||||||
this.totalWeight = data.totpeso;
|
|
||||||
this.loadFormOrder();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getTaxValue() {
|
getTaxValue() {
|
||||||
const taxDelivery = JSON.parse(localStorage.getItem('taxDelivery'));
|
const taxDelivery = JSON.parse(localStorage.getItem('taxDelivery'));
|
||||||
|
if (!this.formResumeOrder) return 0;
|
||||||
const taxValue = Number.parseFloat(
|
const taxValue = Number.parseFloat(
|
||||||
this.formResumeOrder.get('taxValue').value
|
this.formResumeOrder.get('taxValue').value
|
||||||
);
|
);
|
||||||
@@ -345,18 +336,24 @@ export class CartSalesComponent
|
|||||||
return taxDelivery != null ? taxDelivery.taxValue : taxValue;
|
return taxDelivery != null ? taxDelivery.taxValue : taxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadFormOrder() {
|
loadFormOrder(data?: Shopping) {
|
||||||
this.subscriptionShopping = this.shopping$.subscribe((data) => {
|
if (!data && this.shopping) {
|
||||||
const taxDelivery = JSON.parse(localStorage.getItem('taxDelivery'));
|
data = this.shopping;
|
||||||
this.formResumeOrder = this.fb.group({
|
}
|
||||||
taxValue: [
|
if (!data) return;
|
||||||
taxDelivery.taxValue > 0 ? taxDelivery.taxValue.toFixed(2) : '0',
|
|
||||||
],
|
const taxDelivery = JSON.parse(localStorage.getItem('taxDelivery'));
|
||||||
discount: [data.vldesconto > 0 ? data.vldesconto.toFixed(2) : '0,00'],
|
if (this.formResumeOrder) {
|
||||||
carrierId: [taxDelivery.carrierId],
|
this.formResumeOrder.patchValue({
|
||||||
deliveryTaxId: [taxDelivery.deliveryTaxId],
|
taxValue:
|
||||||
|
taxDelivery != null && taxDelivery.taxValue > 0
|
||||||
|
? taxDelivery.taxValue.toFixed(2)
|
||||||
|
: '0',
|
||||||
|
discount: data.vldesconto > 0 ? data.vldesconto.toFixed(2) : '0,00',
|
||||||
|
carrierId: taxDelivery != null ? taxDelivery.carrierId : 0,
|
||||||
|
deliveryTaxId: taxDelivery != null ? taxDelivery.deliveryTaxId : 0,
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@@ -449,6 +446,7 @@ export class CartSalesComponent
|
|||||||
taxValue: new FormControl(this.cartData.taxValue.toFixed(2), []),
|
taxValue: new FormControl(this.cartData.taxValue.toFixed(2), []),
|
||||||
discount: new FormControl(this.cartData.discountValue.toFixed(2), []),
|
discount: new FormControl(this.cartData.discountValue.toFixed(2), []),
|
||||||
carrierId: new FormControl(this.cartData.carrierId, []),
|
carrierId: new FormControl(this.cartData.carrierId, []),
|
||||||
|
deliveryTaxId: new FormControl(0, []),
|
||||||
});
|
});
|
||||||
this.formPayment = this.fb.group({
|
this.formPayment = this.fb.group({
|
||||||
invoiceStore: new FormControl(null),
|
invoiceStore: new FormControl(null),
|
||||||
@@ -499,7 +497,7 @@ export class CartSalesComponent
|
|||||||
this.shopping = data;
|
this.shopping = data;
|
||||||
if (this.shopping !== null) {
|
if (this.shopping !== null) {
|
||||||
this.totalWeight = data.totpeso;
|
this.totalWeight = data.totpeso;
|
||||||
this.loadFormOrder();
|
this.loadFormOrder(data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1432,10 +1430,10 @@ export class CartSalesComponent
|
|||||||
let carrierId = 0;
|
let carrierId = 0;
|
||||||
if (taxValue >= 0) {
|
if (taxValue >= 0) {
|
||||||
deliveryTaxId = Number.parseFloat(
|
deliveryTaxId = Number.parseFloat(
|
||||||
this.formResumeOrder.get('deliveryTaxId').value
|
this.formResumeOrder.get('deliveryTaxId') ? this.formResumeOrder.get('deliveryTaxId').value : 0
|
||||||
);
|
);
|
||||||
carrierId = Number.parseFloat(
|
carrierId = Number.parseFloat(
|
||||||
this.formResumeOrder.get('carrierId').value
|
this.formResumeOrder.get('carrierId') ? this.formResumeOrder.get('carrierId').value : 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const order: OrderDeliveryTax = {
|
const order: OrderDeliveryTax = {
|
||||||
@@ -1446,7 +1444,6 @@ export class CartSalesComponent
|
|||||||
};
|
};
|
||||||
localStorage.setItem('taxDelivery', JSON.stringify(order));
|
localStorage.setItem('taxDelivery', JSON.stringify(order));
|
||||||
this.loadFormOrder();
|
this.loadFormOrder();
|
||||||
this.loadShopping();
|
|
||||||
|
|
||||||
/* this.store.dispatch(new UpdateDeliveryTaxAction(order));
|
/* this.store.dispatch(new UpdateDeliveryTaxAction(order));
|
||||||
this.updating$.subscribe((update) => {
|
this.updating$.subscribe((update) => {
|
||||||
@@ -1588,6 +1585,7 @@ export class CartSalesComponent
|
|||||||
console.log('Retorno cadastro endereço: ' + result);
|
console.log('Retorno cadastro endereço: ' + result);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
localStorage.setItem('address', JSON.stringify(result));
|
localStorage.setItem('address', JSON.stringify(result));
|
||||||
|
this.updateCart(this.shoppingService.getCart());
|
||||||
this.updateFormAddress(result);
|
this.updateFormAddress(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2146,10 +2144,10 @@ export class CartSalesComponent
|
|||||||
);
|
);
|
||||||
let percentOrder = (discountValue / orderValue) * 100;
|
let percentOrder = (discountValue / orderValue) * 100;
|
||||||
console.log('Percentual do pedido: ' + percentOrder);
|
console.log('Percentual do pedido: ' + percentOrder);
|
||||||
if (this.percentSeller < percentOrder) {
|
// if (this.percentSeller < percentOrder) {
|
||||||
this.openedAuthUser = true;
|
// this.openedAuthUser = true;
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
if (discountValue <= 0.01) {
|
if (discountValue <= 0.01) {
|
||||||
percentOrder = 0;
|
percentOrder = 0;
|
||||||
}
|
}
|
||||||
@@ -2159,8 +2157,9 @@ export class CartSalesComponent
|
|||||||
idUserAuth: this.authService.getUser(),
|
idUserAuth: this.authService.getUser(),
|
||||||
};
|
};
|
||||||
this.store.dispatch(new ApplyDiscountOrderAction(order));
|
this.store.dispatch(new ApplyDiscountOrderAction(order));
|
||||||
this.store.dispatch(new LoadShoppingAction(this.shoppingService.getCart()));
|
// this.store.dispatch(new LoadShoppingAction(this.shoppingService.getCart())); // Reloader moved to Effect
|
||||||
this.loadFormOrder();
|
this.loadFormOrder();
|
||||||
|
this.calculateTaxDelivery(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyDiscountOrder() {
|
applyDiscountOrder() {
|
||||||
@@ -2249,6 +2248,7 @@ export class CartSalesComponent
|
|||||||
this.showInformation = true;
|
this.showInformation = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.loadFormOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
calcDiscountOrderValue() {
|
calcDiscountOrderValue() {
|
||||||
@@ -2591,6 +2591,7 @@ export class CartSalesComponent
|
|||||||
priorityDelivery: priorityDelivery,
|
priorityDelivery: priorityDelivery,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log('dataDeliveryTax', JSON.stringify(dataDeliveryTax));
|
||||||
this.shoppingService.calculateDeliveryTax(dataDeliveryTax).subscribe(
|
this.shoppingService.calculateDeliveryTax(dataDeliveryTax).subscribe(
|
||||||
(result) => {
|
(result) => {
|
||||||
this.dataDeliveryTax = result;
|
this.dataDeliveryTax = result;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
|
|||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { ActionsLayout } from '@progress/kendo-angular-dialog';
|
import { ActionsLayout } from '@progress/kendo-angular-dialog';
|
||||||
import { Observable, Subscription } from 'rxjs';
|
import { Observable, Subscription } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { catchError, map } from 'rxjs/operators';
|
||||||
import { AuthService } from 'src/app/auth/services/auth.service';
|
import { AuthService } from 'src/app/auth/services/auth.service';
|
||||||
import { ResultApi } from 'src/app/models/result-api.model';
|
import { ResultApi } from 'src/app/models/result-api.model';
|
||||||
import { UserAuth } from 'src/app/models/user-auth.model';
|
import { UserAuth } from 'src/app/models/user-auth.model';
|
||||||
@@ -55,7 +55,7 @@ export class DiscountItemSalesComponent implements OnInit {
|
|||||||
constructor(
|
constructor(
|
||||||
private fb: FormBuilder,
|
private fb: FormBuilder,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private store: Store<SaleState>, ) {
|
private store: Store<SaleState>,) {
|
||||||
|
|
||||||
this.formDiscountItem = this.fb.group({
|
this.formDiscountItem = this.fb.group({
|
||||||
description: [''],
|
description: [''],
|
||||||
@@ -96,7 +96,7 @@ export class DiscountItemSalesComponent implements OnInit {
|
|||||||
|
|
||||||
calcPercentDiscount() {
|
calcPercentDiscount() {
|
||||||
const discountValue = this.formDiscountItem.get('discountValue').value;
|
const discountValue = this.formDiscountItem.get('discountValue').value;
|
||||||
const percent = Number.parseFloat(( discountValue / this.shoppingItem.listPrice ).toFixed(2)) * 100;
|
const percent = Number.parseFloat((discountValue / this.shoppingItem.listPrice).toFixed(2)) * 100;
|
||||||
const salePrice = Number.parseFloat((this.shoppingItem.listPrice - discountValue).toFixed(2));
|
const salePrice = Number.parseFloat((this.shoppingItem.listPrice - discountValue).toFixed(2));
|
||||||
this.formDiscountItem.patchValue({
|
this.formDiscountItem.patchValue({
|
||||||
discount: percent,
|
discount: percent,
|
||||||
@@ -107,29 +107,27 @@ export class DiscountItemSalesComponent implements OnInit {
|
|||||||
|
|
||||||
async confirmDiscount() {
|
async confirmDiscount() {
|
||||||
let discount = Number.parseFloat(this.formDiscountItem.get('discount').value);
|
let discount = Number.parseFloat(this.formDiscountItem.get('discount').value);
|
||||||
|
console.log('discount', discount);
|
||||||
const discountValue = Number.parseFloat(this.formDiscountItem.get('discountValue').value);
|
const discountValue = Number.parseFloat(this.formDiscountItem.get('discountValue').value);
|
||||||
const salePrice = Number.parseFloat((this.shoppingItem.listPrice - discountValue).toFixed(2));
|
const salePrice = Number.parseFloat((this.shoppingItem.listPrice - discountValue).toFixed(2));
|
||||||
|
|
||||||
if (this.percentSeller < discount) {
|
// if (this.percentSeller < discount) {
|
||||||
this.openedAuthUser = true;
|
// this.openedAuthUser = true;
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (discountValue <= 0.01) {
|
if (discountValue <= 0.01) {
|
||||||
discount = 0;
|
discount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.shoppingItem.discount = discount;
|
console.log('shoppingItem', JSON.stringify(this.shoppingItem));
|
||||||
this.shoppingItem.discountValue = discountValue;
|
const updateItem = { ...this.shoppingItem };
|
||||||
this.shoppingItem.price = salePrice;
|
updateItem.discount = discount;
|
||||||
this.shoppingItem.userDiscount = this.authService.getUser();
|
updateItem.discountValue = discountValue;
|
||||||
this.store.dispatch(new UpdatePriceItemAction(this.shoppingItem));
|
updateItem.price = salePrice;
|
||||||
this.updating$.pipe(
|
updateItem.userDiscount = this.authService.getUser();
|
||||||
map((updating) => {
|
this.store.dispatch(new UpdatePriceItemAction(updateItem));
|
||||||
if (!updating) {
|
this.resultEvent.emit(true);
|
||||||
this.resultEvent.emit(true);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async returnAuthUser(userAuth: any) {
|
async returnAuthUser(userAuth: any) {
|
||||||
@@ -149,13 +147,7 @@ export class DiscountItemSalesComponent implements OnInit {
|
|||||||
updateItem.price = salePrice;
|
updateItem.price = salePrice;
|
||||||
updateItem.userDiscount = userAuth.id;
|
updateItem.userDiscount = userAuth.id;
|
||||||
this.store.dispatch(new UpdatePriceItemAction(updateItem));
|
this.store.dispatch(new UpdatePriceItemAction(updateItem));
|
||||||
this.updating$.subscribe(
|
this.resultEvent.emit(true);
|
||||||
(updating) => {
|
|
||||||
if (!updating) {
|
|
||||||
this.resultEvent.emit(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
console.log('Não localizou o id.');
|
console.log('Não localizou o id.');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,48 +1,33 @@
|
|||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<form class="k-form" [formGroup]="formDiscount">
|
<form class="k-form" [formGroup]="formDiscount">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Dados do pedido</legend>
|
<legend>Dados do pedido xxx</legend>
|
||||||
|
|
||||||
<label class="k-form-field">
|
<label class="k-form-field">
|
||||||
<span>Valor dos produtos</span>
|
<span>Valor dos produtos</span>
|
||||||
<kendo-numerictextbox
|
<kendo-numerictextbox [spinners]="false" [readonly]="true" [value]="orderValue" formControlName="value">
|
||||||
[spinners]="false"
|
|
||||||
[readonly]="true"
|
|
||||||
[value]="orderValue"
|
|
||||||
formControlName="value"
|
|
||||||
>
|
|
||||||
</kendo-numerictextbox>
|
</kendo-numerictextbox>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div class="">
|
<div class="">
|
||||||
<label class="k-form-field">
|
<label class="k-form-field">
|
||||||
<span>% Desconto desejado</span>
|
<span>% Desconto desejado</span>
|
||||||
<kendo-numerictextbox
|
<kendo-numerictextbox formControlName="discount" [spinners]="false">
|
||||||
formControlName="discount"
|
<kendo-formerror>Error: Percentual acima do permitido para o usuário.</kendo-formerror>
|
||||||
[spinners]="false"
|
|
||||||
>
|
|
||||||
<kendo-formerror>Error: Percentual acima do permitido para o usuário.</kendo-formerror>
|
|
||||||
</kendo-numerictextbox>
|
</kendo-numerictextbox>
|
||||||
</label>
|
</label>
|
||||||
<label class="k-form-field">
|
<label class="k-form-field">
|
||||||
<span>Valor do desconto</span>
|
<span>Valor do desconto</span>
|
||||||
<kendo-numerictextbox
|
<kendo-numerictextbox formControlName="discountValue" [spinners]="false">
|
||||||
formControlName="discountValue"
|
<kendo-formerror>Error: Percentual acima do permitido para o usuário.</kendo-formerror>
|
||||||
[spinners]="false"
|
|
||||||
>
|
|
||||||
<kendo-formerror>Error: Percentual acima do permitido para o usuário.</kendo-formerror>
|
|
||||||
</kendo-numerictextbox>
|
</kendo-numerictextbox>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label class="k-form-field">
|
<label class="k-form-field">
|
||||||
<span>Valor do pedido com desconto</span>
|
<span>Valor do pedido com desconto</span>
|
||||||
<kendo-numerictextbox
|
<kendo-numerictextbox formcontrolName="valueWithDiscount" [spinners]="false" [readonly]="true"
|
||||||
formcontrolName="valueWithDiscount"
|
[value]="orderWithDiscount">
|
||||||
[spinners]="false"
|
|
||||||
[readonly]="true"
|
|
||||||
[value]="orderWithDiscount"
|
|
||||||
>
|
|
||||||
</kendo-numerictextbox>
|
</kendo-numerictextbox>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@@ -51,7 +36,7 @@
|
|||||||
<div formGroupName="formGroup">
|
<div formGroupName="formGroup">
|
||||||
<label class="k-label">
|
<label class="k-label">
|
||||||
<input type="checkbox" formControlName="userAuth" kendoCheckBox />
|
<input type="checkbox" formControlName="userAuth" kendoCheckBox />
|
||||||
<span class="ms-2">Informar outro usuário para autorizar o desconto</span>
|
<span class="ms-2">Informar outro usuário para autorizar o desconto</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -60,12 +45,7 @@
|
|||||||
<fieldset>
|
<fieldset>
|
||||||
<kendo-formfield>
|
<kendo-formfield>
|
||||||
<kendo-label [for]="email" text="Email"></kendo-label>
|
<kendo-label [for]="email" text="Email"></kendo-label>
|
||||||
<kendo-textbox
|
<kendo-textbox formControlName="email" [clearButton]="true" #email required></kendo-textbox>
|
||||||
formControlName="email"
|
|
||||||
[clearButton]="true"
|
|
||||||
#email
|
|
||||||
required
|
|
||||||
></kendo-textbox>
|
|
||||||
|
|
||||||
<!--kendo-formerror *ngIf="formDiscount.controls.formUser.email.errors?.required"
|
<!--kendo-formerror *ngIf="formDiscount.controls.formUser.email.errors?.required"
|
||||||
>Erro: Email é obrigatório</kendo-formerror
|
>Erro: Email é obrigatório</kendo-formerror
|
||||||
@@ -77,13 +57,7 @@
|
|||||||
|
|
||||||
<kendo-formfield class="mt-2">
|
<kendo-formfield class="mt-2">
|
||||||
<kendo-label [for]="password" text="Senha"></kendo-label>
|
<kendo-label [for]="password" text="Senha"></kendo-label>
|
||||||
<input
|
<input kendoTextBox type="password" placeholder="Password" #password formControlName="password" />
|
||||||
kendoTextBox
|
|
||||||
type="password"
|
|
||||||
placeholder="Password"
|
|
||||||
#password
|
|
||||||
formControlName="password"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<kendo-formerror>Error: Password is required</kendo-formerror>
|
<kendo-formerror>Error: Password is required</kendo-formerror>
|
||||||
</kendo-formfield>
|
</kendo-formfield>
|
||||||
@@ -92,23 +66,24 @@
|
|||||||
|
|
||||||
|
|
||||||
<div class="k-actions k-actions-end">
|
<div class="k-actions k-actions-end">
|
||||||
<button type="button" [disabled]="!formDiscount.valid" class="k-button" (click)="closeMsgDiscount()">Cancel</button>
|
<button type="button" [disabled]="!formDiscount.valid" class="k-button"
|
||||||
<button type="button" class="k-button k-primary" (click)="confirmDiscount()" >Submit</button>
|
(click)="closeMsgDiscount()">Cancel</button>
|
||||||
|
<button type="button" class="k-button k-primary" (click)="confirmDiscount()">Submit</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
<kendo-dialog title="Pedido de venda" *ngIf="openedMsgDiscount" (close)="close()">
|
<kendo-dialog title="Pedido de venda" *ngIf="openedMsgDiscount" (close)="close()">
|
||||||
<p style="margin: 25px; text-align: center;">Desconto acima do permitido para o usuário!</p>
|
<p style="margin: 25px; text-align: center;">Desconto acima do permitido para o usuário!</p>
|
||||||
<p>Percentual máximo permitido é de {{discountAuthorization}}%</p>
|
<p>Percentual máximo permitido é de {{discountAuthorization}}%</p>
|
||||||
<p>Informado no pedido foi de {{percent}}%</p>
|
<p>Informado no pedido foi de {{percent}}%</p>
|
||||||
|
|
||||||
<kendo-dialog-actions>
|
<kendo-dialog-actions>
|
||||||
<button kendoButton (click)="close()" [primary]="true">
|
<button kendoButton (click)="close()" [primary]="true">
|
||||||
Yes, sorry.
|
Yes, sorry.
|
||||||
</button>
|
</button>
|
||||||
</kendo-dialog-actions>
|
</kendo-dialog-actions>
|
||||||
</kendo-dialog>
|
</kendo-dialog>
|
||||||
</div>
|
</div>
|
||||||
@@ -43,13 +43,13 @@ export class DiscountOrderComponent implements OnInit, OnDestroy {
|
|||||||
discountValue: [(this.orderValue - this.orderWithDiscount),
|
discountValue: [(this.orderValue - this.orderWithDiscount),
|
||||||
Validators.compose([Validators.required])],
|
Validators.compose([Validators.required])],
|
||||||
valueWithDiscount: [this.orderWithDiscount, [Validators.required]],
|
valueWithDiscount: [this.orderWithDiscount, [Validators.required]],
|
||||||
formUser: this.formBuilder.group({
|
// formUser: this.formBuilder.group({
|
||||||
email: new FormControl(null, Validators.required),
|
// email: new FormControl(null, Validators.required),
|
||||||
password: new FormControl(null, Validators.required),
|
// password: new FormControl(null, Validators.required),
|
||||||
}),
|
// }),
|
||||||
formGroup: this.formBuilder.group({
|
// formGroup: this.formBuilder.group({
|
||||||
userAuth: new FormControl(null, Validators.required),
|
// userAuth: new FormControl(null, Validators.required),
|
||||||
}),
|
// }),
|
||||||
});
|
});
|
||||||
this.formDiscount.valueChanges.subscribe(f => {
|
this.formDiscount.valueChanges.subscribe(f => {
|
||||||
this.percent = this.formDiscount.get('discount').value;
|
this.percent = this.formDiscount.get('discount').value;
|
||||||
@@ -84,78 +84,82 @@ export class DiscountOrderComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
confirmDiscount() {
|
confirmDiscount() {
|
||||||
|
|
||||||
|
this.submitForm.emit(this.formDiscount);
|
||||||
|
return;
|
||||||
|
|
||||||
let email = this.formDiscount.get('formUser.email').value;
|
let email = this.formDiscount.get('formUser.email').value;
|
||||||
|
|
||||||
const emailUpperCase = email.toUpperCase();
|
const emailUpperCase = email.toUpperCase();
|
||||||
const passwordUpperCase = this.formDiscount.get('formUser.password').value.toUpperCase();
|
const passwordUpperCase = this.formDiscount.get('formUser.password').value.toUpperCase();
|
||||||
|
|
||||||
if (this.discountAuthorization < this.percent) {
|
// if (this.discountAuthorization < this.percent) {
|
||||||
if (this.formDiscount.controls.formGroup.get('userAuth').value) {
|
if (this.formDiscount.controls.formGroup.get('userAuth').value) {
|
||||||
this.SubscriptionAuth = this.authService.authenticate({
|
this.SubscriptionAuth = this.authService.authenticate({
|
||||||
email: emailUpperCase,
|
email: emailUpperCase,
|
||||||
password: passwordUpperCase
|
password: passwordUpperCase
|
||||||
})
|
|
||||||
.subscribe((res: ResultApi) => {
|
|
||||||
console.log(res);
|
|
||||||
if (res.success) {
|
|
||||||
this.discountAuthorization = res.data.discountPercent;
|
|
||||||
if (this.discountAuthorization < this.percent) {
|
|
||||||
this.openedMsgDiscount = true;
|
|
||||||
} else {
|
|
||||||
console.log('fechar form');
|
|
||||||
this.submitForm.emit(this.formDiscount);
|
|
||||||
}
|
|
||||||
// this.loadingIcon = '';
|
|
||||||
} else {
|
|
||||||
// this.loadingIcon = '';
|
|
||||||
// this.showErrorMessage(res.message);
|
|
||||||
}
|
|
||||||
}, err => {
|
|
||||||
// this.loadingIcon = '';
|
|
||||||
// this.showErrorMessage('Erro ao processar sua requisição,
|
|
||||||
// tente novamente e caso persista o erro contacte o departamento de TI.');
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.openedMsgDiscount = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getAuthorization() {
|
|
||||||
return this.formDiscount.controls.formGroup.get('userAuth').value;
|
|
||||||
}
|
|
||||||
|
|
||||||
validationUser() {
|
|
||||||
this.formDiscount.markAllAsTouched();
|
|
||||||
if (this.formDiscount.valid) {
|
|
||||||
// this.loadingIcon = 'loading';
|
|
||||||
this.authService.authenticate({
|
|
||||||
email: this.formDiscount.get('formUser.email').value,
|
|
||||||
password: this.formDiscount.get('formUser.password').value
|
|
||||||
})
|
})
|
||||||
.subscribe((res: ResultApi) => {
|
.subscribe((res: ResultApi) => {
|
||||||
console.log(res);
|
console.log(res);
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
this.discountAuthorization = res.data.discountPercent;
|
this.discountAuthorization = res.data.discountPercent;
|
||||||
return this.discountAuthorization;
|
if (this.discountAuthorization < this.percent) {
|
||||||
|
this.openedMsgDiscount = true;
|
||||||
|
} else {
|
||||||
|
console.log('fechar form');
|
||||||
|
this.submitForm.emit(this.formDiscount);
|
||||||
|
}
|
||||||
// this.loadingIcon = '';
|
// this.loadingIcon = '';
|
||||||
} else {
|
} else {
|
||||||
// this.loadingIcon = '';
|
// this.loadingIcon = '';
|
||||||
// this.showErrorMessage(res.message);
|
// this.showErrorMessage(res.message);
|
||||||
return this.discountAuthorization;
|
|
||||||
}
|
}
|
||||||
}, err => {
|
}, err => {
|
||||||
return this.discountAuthorization;
|
|
||||||
// this.loadingIcon = '';
|
// this.loadingIcon = '';
|
||||||
// this.showErrorMessage('Erro ao processar sua requisição,
|
// this.showErrorMessage('Erro ao processar sua requisição,
|
||||||
// tente novamente e caso persista o erro contacte o departamento de TI.');
|
// tente novamente e caso persista o erro contacte o departamento de TI.');
|
||||||
});
|
});
|
||||||
return this.discountAuthorization;
|
} else {
|
||||||
|
this.openedMsgDiscount = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// } else {
|
||||||
|
// this.close();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
getAuthorization() {
|
||||||
|
return false; //this.formDiscount.controls.formGroup.get('userAuth').value;
|
||||||
|
}
|
||||||
|
|
||||||
|
validationUser() {
|
||||||
|
this.formDiscount.markAllAsTouched();
|
||||||
|
// if (this.formDiscount.valid) {
|
||||||
|
// // this.loadingIcon = 'loading';
|
||||||
|
// this.authService.authenticate({
|
||||||
|
// email: this.formDiscount.get('formUser.email').value,
|
||||||
|
// password: this.formDiscount.get('formUser.password').value
|
||||||
|
// })
|
||||||
|
// .subscribe((res: ResultApi) => {
|
||||||
|
// console.log(res);
|
||||||
|
// if (res.success) {
|
||||||
|
// this.discountAuthorization = res.data.discountPercent;
|
||||||
|
// return this.discountAuthorization;
|
||||||
|
// // this.loadingIcon = '';
|
||||||
|
// } else {
|
||||||
|
// // this.loadingIcon = '';
|
||||||
|
// // this.showErrorMessage(res.message);
|
||||||
|
// return this.discountAuthorization;
|
||||||
|
// }
|
||||||
|
// }, err => {
|
||||||
|
// return this.discountAuthorization;
|
||||||
|
// // this.loadingIcon = '';
|
||||||
|
// // this.showErrorMessage('Erro ao processar sua requisição,
|
||||||
|
// // tente novamente e caso persista o erro contacte o departamento de TI.');
|
||||||
|
// });
|
||||||
|
// return this.discountAuthorization;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 col-sm-12 mt-3 mt-md-0">
|
<div class="col-md-6 col-sm-12 mt-3 mt-md-0">
|
||||||
<label>
|
<label>
|
||||||
<span class="d-block">CPF / CNPJ</span>
|
<span class="d-block">CPF / CNPJ ou</span>
|
||||||
|
<span class="d-block">Código do Cliente</span>
|
||||||
<kendo-textbox formControlName="document" placeholder="Informe o CPF ou CNPJ do cliente"></kendo-textbox>
|
<kendo-textbox formControlName="document" placeholder="Informe o CPF ou CNPJ do cliente"></kendo-textbox>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -98,7 +98,10 @@ export class ShoppingEffects {
|
|||||||
mergeMap(
|
mergeMap(
|
||||||
(data) => this.shoppingService.updatePriceItemShopping(data.payload)
|
(data) => this.shoppingService.updatePriceItemShopping(data.payload)
|
||||||
.pipe(
|
.pipe(
|
||||||
map(() => new UpdatePriceItemSuccessAction(data.payload)),
|
mergeMap(() => [
|
||||||
|
new UpdatePriceItemSuccessAction(data.payload),
|
||||||
|
new LoadShoppingAction(data.payload.idCart)
|
||||||
|
]),
|
||||||
catchError(error => of(new UpdatePriceItemFailureAction(error)))
|
catchError(error => of(new UpdatePriceItemFailureAction(error)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -110,7 +113,10 @@ export class ShoppingEffects {
|
|||||||
mergeMap(
|
mergeMap(
|
||||||
(data) => this.shoppingService.applyDiscountOrder(data.payload)
|
(data) => this.shoppingService.applyDiscountOrder(data.payload)
|
||||||
.pipe(
|
.pipe(
|
||||||
map((items) => new ApplyDiscountOrderSuccessAction(items)),
|
mergeMap((items) => [
|
||||||
|
new ApplyDiscountOrderSuccessAction(items),
|
||||||
|
new LoadShoppingAction(data.payload.id)
|
||||||
|
]),
|
||||||
catchError(error => of(new ApplyDiscountOrderFailureAction(error)))
|
catchError(error => of(new ApplyDiscountOrderFailureAction(error)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -122,7 +128,10 @@ export class ShoppingEffects {
|
|||||||
mergeMap(
|
mergeMap(
|
||||||
(data) => this.shoppingService.updateQuantityItemShopping(data.payload)
|
(data) => this.shoppingService.updateQuantityItemShopping(data.payload)
|
||||||
.pipe(
|
.pipe(
|
||||||
map(() => new UpdateQuantityItemSuccessAction(data.payload)),
|
mergeMap(() => [
|
||||||
|
new UpdateQuantityItemSuccessAction(data.payload),
|
||||||
|
new LoadShoppingAction(data.payload.idCart)
|
||||||
|
]),
|
||||||
catchError(error => of(new UpdateQuantityItemFailureAction(error)))
|
catchError(error => of(new UpdateQuantityItemFailureAction(error)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -134,7 +143,10 @@ export class ShoppingEffects {
|
|||||||
mergeMap(
|
mergeMap(
|
||||||
(data) => this.shoppingService.deleteItemShopping(data.payload)
|
(data) => this.shoppingService.deleteItemShopping(data.payload)
|
||||||
.pipe(
|
.pipe(
|
||||||
map((result) => new DeleteItemSuccessAction(result)),
|
mergeMap((result) => [
|
||||||
|
new DeleteItemSuccessAction(result),
|
||||||
|
new LoadShoppingAction(localStorage.getItem('cart'))
|
||||||
|
]),
|
||||||
catchError(error => of(new DeleteItemFailureAction(error)))
|
catchError(error => of(new DeleteItemFailureAction(error)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export const environment = {
|
export const environment = {
|
||||||
production: true,
|
production: true,
|
||||||
// url: 'http://10.1.1.124:8065/api/v1/',
|
// url: 'http://172.35.0.217:32619/api/v1/',
|
||||||
url: 'https://api.vendaweb.simplifiquehc.com.br/api/v1/',
|
url: 'https://api.vendaweb.simplifiquehc.com.br/api/v1/',
|
||||||
// url: 'http://vendaweb.jurunense.com.br/api/v1/',
|
// url: 'http://vendaweb.jurunense.com.br/api/v1/',
|
||||||
URL_PIX: 'http://10.1.1.205:8078/api/v1/',
|
URL_PIX: 'http://10.1.1.205:8078/api/v1/',
|
||||||
|
|||||||
Reference in New Issue
Block a user