parent
ce1ca0a60c
commit
a1883a025c
@ -0,0 +1,23 @@ |
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. |
||||||
|
|
||||||
|
# dependencies |
||||||
|
/node_modules |
||||||
|
/.pnp |
||||||
|
.pnp.js |
||||||
|
|
||||||
|
# testing |
||||||
|
/coverage |
||||||
|
|
||||||
|
# production |
||||||
|
/build |
||||||
|
|
||||||
|
# misc |
||||||
|
.DS_Store |
||||||
|
.env.local |
||||||
|
.env.development.local |
||||||
|
.env.test.local |
||||||
|
.env.production.local |
||||||
|
|
||||||
|
npm-debug.log* |
||||||
|
yarn-debug.log* |
||||||
|
yarn-error.log* |
@ -0,0 +1,7 @@ |
|||||||
|
{ |
||||||
|
"recommendations": [ |
||||||
|
"dzhavat.bracket-pair-toggler", |
||||||
|
"bracketpaircolordlw.bracket-pair-color-dlw", |
||||||
|
"2gua.rainbow-brackets" |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
import { defineConfig } from "cypress"; |
||||||
|
|
||||||
|
export default defineConfig({ |
||||||
|
e2e: { |
||||||
|
setupNodeEvents(on, config) { |
||||||
|
// implement node event listeners here
|
||||||
|
}, |
||||||
|
baseUrl: "http://localhost:3000", |
||||||
|
}, |
||||||
|
waitForAnimations: false, |
||||||
|
animationDistanceThreshold: 50, |
||||||
|
}); |
@ -0,0 +1,143 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
// Welcome to Cypress!
|
||||||
|
//
|
||||||
|
// This spec file contains a variety of sample tests
|
||||||
|
// for a todo list app that are designed to demonstrate
|
||||||
|
// the power of writing tests in Cypress.
|
||||||
|
//
|
||||||
|
// To learn more about how Cypress works and
|
||||||
|
// what makes it such an awesome testing tool,
|
||||||
|
// please read our getting started guide:
|
||||||
|
// https://on.cypress.io/introduction-to-cypress
|
||||||
|
|
||||||
|
describe('example to-do app', () => { |
||||||
|
beforeEach(() => { |
||||||
|
// Cypress starts out with a blank slate for each test
|
||||||
|
// so we must tell it to visit our website with the `cy.visit()` command.
|
||||||
|
// Since we want to visit the same URL at the start of all our tests,
|
||||||
|
// we include it in our beforeEach function so that it runs before each test
|
||||||
|
cy.visit('https://example.cypress.io/todo') |
||||||
|
}) |
||||||
|
|
||||||
|
it('displays two todo items by default', () => { |
||||||
|
// We use the `cy.get()` command to get all elements that match the selector.
|
||||||
|
// Then, we use `should` to assert that there are two matched items,
|
||||||
|
// which are the two default items.
|
||||||
|
cy.get('.todo-list li').should('have.length', 2) |
||||||
|
|
||||||
|
// We can go even further and check that the default todos each contain
|
||||||
|
// the correct text. We use the `first` and `last` functions
|
||||||
|
// to get just the first and last matched elements individually,
|
||||||
|
// and then perform an assertion with `should`.
|
||||||
|
cy.get('.todo-list li').first().should('have.text', 'Pay electric bill') |
||||||
|
cy.get('.todo-list li').last().should('have.text', 'Walk the dog') |
||||||
|
}) |
||||||
|
|
||||||
|
it('can add new todo items', () => { |
||||||
|
// We'll store our item text in a variable so we can reuse it
|
||||||
|
const newItem = 'Feed the cat' |
||||||
|
|
||||||
|
// Let's get the input element and use the `type` command to
|
||||||
|
// input our new list item. After typing the content of our item,
|
||||||
|
// we need to type the enter key as well in order to submit the input.
|
||||||
|
// This input has a data-test attribute so we'll use that to select the
|
||||||
|
// element in accordance with best practices:
|
||||||
|
// https://on.cypress.io/selecting-elements
|
||||||
|
cy.get('[data-test=new-todo]').type(`${newItem}{enter}`) |
||||||
|
|
||||||
|
// Now that we've typed our new item, let's check that it actually was added to the list.
|
||||||
|
// Since it's the newest item, it should exist as the last element in the list.
|
||||||
|
// In addition, with the two default items, we should have a total of 3 elements in the list.
|
||||||
|
// Since assertions yield the element that was asserted on,
|
||||||
|
// we can chain both of these assertions together into a single statement.
|
||||||
|
cy.get('.todo-list li') |
||||||
|
.should('have.length', 3) |
||||||
|
.last() |
||||||
|
.should('have.text', newItem) |
||||||
|
}) |
||||||
|
|
||||||
|
it('can check off an item as completed', () => { |
||||||
|
// In addition to using the `get` command to get an element by selector,
|
||||||
|
// we can also use the `contains` command to get an element by its contents.
|
||||||
|
// However, this will yield the <label>, which is lowest-level element that contains the text.
|
||||||
|
// In order to check the item, we'll find the <input> element for this <label>
|
||||||
|
// by traversing up the dom to the parent element. From there, we can `find`
|
||||||
|
// the child checkbox <input> element and use the `check` command to check it.
|
||||||
|
cy.contains('Pay electric bill') |
||||||
|
.parent() |
||||||
|
.find('input[type=checkbox]') |
||||||
|
.check() |
||||||
|
|
||||||
|
// Now that we've checked the button, we can go ahead and make sure
|
||||||
|
// that the list element is now marked as completed.
|
||||||
|
// Again we'll use `contains` to find the <label> element and then use the `parents` command
|
||||||
|
// to traverse multiple levels up the dom until we find the corresponding <li> element.
|
||||||
|
// Once we get that element, we can assert that it has the completed class.
|
||||||
|
cy.contains('Pay electric bill') |
||||||
|
.parents('li') |
||||||
|
.should('have.class', 'completed') |
||||||
|
}) |
||||||
|
|
||||||
|
context('with a checked task', () => { |
||||||
|
beforeEach(() => { |
||||||
|
// We'll take the command we used above to check off an element
|
||||||
|
// Since we want to perform multiple tests that start with checking
|
||||||
|
// one element, we put it in the beforeEach hook
|
||||||
|
// so that it runs at the start of every test.
|
||||||
|
cy.contains('Pay electric bill') |
||||||
|
.parent() |
||||||
|
.find('input[type=checkbox]') |
||||||
|
.check() |
||||||
|
}) |
||||||
|
|
||||||
|
it('can filter for uncompleted tasks', () => { |
||||||
|
// We'll click on the "active" button in order to
|
||||||
|
// display only incomplete items
|
||||||
|
cy.contains('Active').click() |
||||||
|
|
||||||
|
// After filtering, we can assert that there is only the one
|
||||||
|
// incomplete item in the list.
|
||||||
|
cy.get('.todo-list li') |
||||||
|
.should('have.length', 1) |
||||||
|
.first() |
||||||
|
.should('have.text', 'Walk the dog') |
||||||
|
|
||||||
|
// For good measure, let's also assert that the task we checked off
|
||||||
|
// does not exist on the page.
|
||||||
|
cy.contains('Pay electric bill').should('not.exist') |
||||||
|
}) |
||||||
|
|
||||||
|
it('can filter for completed tasks', () => { |
||||||
|
// We can perform similar steps as the test above to ensure
|
||||||
|
// that only completed tasks are shown
|
||||||
|
cy.contains('Completed').click() |
||||||
|
|
||||||
|
cy.get('.todo-list li') |
||||||
|
.should('have.length', 1) |
||||||
|
.first() |
||||||
|
.should('have.text', 'Pay electric bill') |
||||||
|
|
||||||
|
cy.contains('Walk the dog').should('not.exist') |
||||||
|
}) |
||||||
|
|
||||||
|
it('can delete all completed tasks', () => { |
||||||
|
// First, let's click the "Clear completed" button
|
||||||
|
// `contains` is actually serving two purposes here.
|
||||||
|
// First, it's ensuring that the button exists within the dom.
|
||||||
|
// This button only appears when at least one task is checked
|
||||||
|
// so this command is implicitly verifying that it does exist.
|
||||||
|
// Second, it selects the button so we can click it.
|
||||||
|
cy.contains('Clear completed').click() |
||||||
|
|
||||||
|
// Then we can make sure that there is only one element
|
||||||
|
// in the list and our element does not exist
|
||||||
|
cy.get('.todo-list li') |
||||||
|
.should('have.length', 1) |
||||||
|
.should('not.have.text', 'Pay electric bill') |
||||||
|
|
||||||
|
// Finally, make sure that the clear button no longer exists.
|
||||||
|
cy.contains('Clear completed').should('not.exist') |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,299 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Actions', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/commands/actions') |
||||||
|
}) |
||||||
|
|
||||||
|
// https://on.cypress.io/interacting-with-elements
|
||||||
|
|
||||||
|
it('.type() - type into a DOM element', () => { |
||||||
|
// https://on.cypress.io/type
|
||||||
|
cy.get('.action-email') |
||||||
|
.type('fake@email.com').should('have.value', 'fake@email.com') |
||||||
|
|
||||||
|
// .type() with special character sequences
|
||||||
|
.type('{leftarrow}{rightarrow}{uparrow}{downarrow}') |
||||||
|
.type('{del}{selectall}{backspace}') |
||||||
|
|
||||||
|
// .type() with key modifiers
|
||||||
|
.type('{alt}{option}') //these are equivalent
|
||||||
|
.type('{ctrl}{control}') //these are equivalent
|
||||||
|
.type('{meta}{command}{cmd}') //these are equivalent
|
||||||
|
.type('{shift}') |
||||||
|
|
||||||
|
// Delay each keypress by 0.1 sec
|
||||||
|
.type('slow.typing@email.com', { delay: 100 }) |
||||||
|
.should('have.value', 'slow.typing@email.com') |
||||||
|
|
||||||
|
cy.get('.action-disabled') |
||||||
|
// Ignore error checking prior to type
|
||||||
|
// like whether the input is visible or disabled
|
||||||
|
.type('disabled error checking', { force: true }) |
||||||
|
.should('have.value', 'disabled error checking') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.focus() - focus on a DOM element', () => { |
||||||
|
// https://on.cypress.io/focus
|
||||||
|
cy.get('.action-focus').focus() |
||||||
|
.should('have.class', 'focus') |
||||||
|
.prev().should('have.attr', 'style', 'color: orange;') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.blur() - blur off a DOM element', () => { |
||||||
|
// https://on.cypress.io/blur
|
||||||
|
cy.get('.action-blur').type('About to blur').blur() |
||||||
|
.should('have.class', 'error') |
||||||
|
.prev().should('have.attr', 'style', 'color: red;') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.clear() - clears an input or textarea element', () => { |
||||||
|
// https://on.cypress.io/clear
|
||||||
|
cy.get('.action-clear').type('Clear this text') |
||||||
|
.should('have.value', 'Clear this text') |
||||||
|
.clear() |
||||||
|
.should('have.value', '') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.submit() - submit a form', () => { |
||||||
|
// https://on.cypress.io/submit
|
||||||
|
cy.get('.action-form') |
||||||
|
.find('[type="text"]').type('HALFOFF') |
||||||
|
|
||||||
|
cy.get('.action-form').submit() |
||||||
|
.next().should('contain', 'Your form has been submitted!') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.click() - click on a DOM element', () => { |
||||||
|
// https://on.cypress.io/click
|
||||||
|
cy.get('.action-btn').click() |
||||||
|
|
||||||
|
// You can click on 9 specific positions of an element:
|
||||||
|
// -----------------------------------
|
||||||
|
// | topLeft top topRight |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | left center right |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | bottomLeft bottom bottomRight |
|
||||||
|
// -----------------------------------
|
||||||
|
|
||||||
|
// clicking in the center of the element is the default
|
||||||
|
cy.get('#action-canvas').click() |
||||||
|
|
||||||
|
cy.get('#action-canvas').click('topLeft') |
||||||
|
cy.get('#action-canvas').click('top') |
||||||
|
cy.get('#action-canvas').click('topRight') |
||||||
|
cy.get('#action-canvas').click('left') |
||||||
|
cy.get('#action-canvas').click('right') |
||||||
|
cy.get('#action-canvas').click('bottomLeft') |
||||||
|
cy.get('#action-canvas').click('bottom') |
||||||
|
cy.get('#action-canvas').click('bottomRight') |
||||||
|
|
||||||
|
// .click() accepts an x and y coordinate
|
||||||
|
// that controls where the click occurs :)
|
||||||
|
|
||||||
|
cy.get('#action-canvas') |
||||||
|
.click(80, 75) // click 80px on x coord and 75px on y coord
|
||||||
|
.click(170, 75) |
||||||
|
.click(80, 165) |
||||||
|
.click(100, 185) |
||||||
|
.click(125, 190) |
||||||
|
.click(150, 185) |
||||||
|
.click(170, 165) |
||||||
|
|
||||||
|
// click multiple elements by passing multiple: true
|
||||||
|
cy.get('.action-labels>.label').click({ multiple: true }) |
||||||
|
|
||||||
|
// Ignore error checking prior to clicking
|
||||||
|
cy.get('.action-opacity>.btn').click({ force: true }) |
||||||
|
}) |
||||||
|
|
||||||
|
it('.dblclick() - double click on a DOM element', () => { |
||||||
|
// https://on.cypress.io/dblclick
|
||||||
|
|
||||||
|
// Our app has a listener on 'dblclick' event in our 'scripts.js'
|
||||||
|
// that hides the div and shows an input on double click
|
||||||
|
cy.get('.action-div').dblclick().should('not.be.visible') |
||||||
|
cy.get('.action-input-hidden').should('be.visible') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.rightclick() - right click on a DOM element', () => { |
||||||
|
// https://on.cypress.io/rightclick
|
||||||
|
|
||||||
|
// Our app has a listener on 'contextmenu' event in our 'scripts.js'
|
||||||
|
// that hides the div and shows an input on right click
|
||||||
|
cy.get('.rightclick-action-div').rightclick().should('not.be.visible') |
||||||
|
cy.get('.rightclick-action-input-hidden').should('be.visible') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.check() - check a checkbox or radio element', () => { |
||||||
|
// https://on.cypress.io/check
|
||||||
|
|
||||||
|
// By default, .check() will check all
|
||||||
|
// matching checkbox or radio elements in succession, one after another
|
||||||
|
cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]') |
||||||
|
.check().should('be.checked') |
||||||
|
|
||||||
|
cy.get('.action-radios [type="radio"]').not('[disabled]') |
||||||
|
.check().should('be.checked') |
||||||
|
|
||||||
|
// .check() accepts a value argument
|
||||||
|
cy.get('.action-radios [type="radio"]') |
||||||
|
.check('radio1').should('be.checked') |
||||||
|
|
||||||
|
// .check() accepts an array of values
|
||||||
|
cy.get('.action-multiple-checkboxes [type="checkbox"]') |
||||||
|
.check(['checkbox1', 'checkbox2']).should('be.checked') |
||||||
|
|
||||||
|
// Ignore error checking prior to checking
|
||||||
|
cy.get('.action-checkboxes [disabled]') |
||||||
|
.check({ force: true }).should('be.checked') |
||||||
|
|
||||||
|
cy.get('.action-radios [type="radio"]') |
||||||
|
.check('radio3', { force: true }).should('be.checked') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.uncheck() - uncheck a checkbox element', () => { |
||||||
|
// https://on.cypress.io/uncheck
|
||||||
|
|
||||||
|
// By default, .uncheck() will uncheck all matching
|
||||||
|
// checkbox elements in succession, one after another
|
||||||
|
cy.get('.action-check [type="checkbox"]') |
||||||
|
.not('[disabled]') |
||||||
|
.uncheck().should('not.be.checked') |
||||||
|
|
||||||
|
// .uncheck() accepts a value argument
|
||||||
|
cy.get('.action-check [type="checkbox"]') |
||||||
|
.check('checkbox1') |
||||||
|
.uncheck('checkbox1').should('not.be.checked') |
||||||
|
|
||||||
|
// .uncheck() accepts an array of values
|
||||||
|
cy.get('.action-check [type="checkbox"]') |
||||||
|
.check(['checkbox1', 'checkbox3']) |
||||||
|
.uncheck(['checkbox1', 'checkbox3']).should('not.be.checked') |
||||||
|
|
||||||
|
// Ignore error checking prior to unchecking
|
||||||
|
cy.get('.action-check [disabled]') |
||||||
|
.uncheck({ force: true }).should('not.be.checked') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.select() - select an option in a <select> element', () => { |
||||||
|
// https://on.cypress.io/select
|
||||||
|
|
||||||
|
// at first, no option should be selected
|
||||||
|
cy.get('.action-select') |
||||||
|
.should('have.value', '--Select a fruit--') |
||||||
|
|
||||||
|
// Select option(s) with matching text content
|
||||||
|
cy.get('.action-select').select('apples') |
||||||
|
// confirm the apples were selected
|
||||||
|
// note that each value starts with "fr-" in our HTML
|
||||||
|
cy.get('.action-select').should('have.value', 'fr-apples') |
||||||
|
|
||||||
|
cy.get('.action-select-multiple') |
||||||
|
.select(['apples', 'oranges', 'bananas']) |
||||||
|
// when getting multiple values, invoke "val" method first
|
||||||
|
.invoke('val') |
||||||
|
.should('deep.equal', ['fr-apples', 'fr-oranges', 'fr-bananas']) |
||||||
|
|
||||||
|
// Select option(s) with matching value
|
||||||
|
cy.get('.action-select').select('fr-bananas') |
||||||
|
// can attach an assertion right away to the element
|
||||||
|
.should('have.value', 'fr-bananas') |
||||||
|
|
||||||
|
cy.get('.action-select-multiple') |
||||||
|
.select(['fr-apples', 'fr-oranges', 'fr-bananas']) |
||||||
|
.invoke('val') |
||||||
|
.should('deep.equal', ['fr-apples', 'fr-oranges', 'fr-bananas']) |
||||||
|
|
||||||
|
// assert the selected values include oranges
|
||||||
|
cy.get('.action-select-multiple') |
||||||
|
.invoke('val').should('include', 'fr-oranges') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.scrollIntoView() - scroll an element into view', () => { |
||||||
|
// https://on.cypress.io/scrollintoview
|
||||||
|
|
||||||
|
// normally all of these buttons are hidden,
|
||||||
|
// because they're not within
|
||||||
|
// the viewable area of their parent
|
||||||
|
// (we need to scroll to see them)
|
||||||
|
cy.get('#scroll-horizontal button') |
||||||
|
.should('not.be.visible') |
||||||
|
|
||||||
|
// scroll the button into view, as if the user had scrolled
|
||||||
|
cy.get('#scroll-horizontal button').scrollIntoView() |
||||||
|
.should('be.visible') |
||||||
|
|
||||||
|
cy.get('#scroll-vertical button') |
||||||
|
.should('not.be.visible') |
||||||
|
|
||||||
|
// Cypress handles the scroll direction needed
|
||||||
|
cy.get('#scroll-vertical button').scrollIntoView() |
||||||
|
.should('be.visible') |
||||||
|
|
||||||
|
cy.get('#scroll-both button') |
||||||
|
.should('not.be.visible') |
||||||
|
|
||||||
|
// Cypress knows to scroll to the right and down
|
||||||
|
cy.get('#scroll-both button').scrollIntoView() |
||||||
|
.should('be.visible') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.trigger() - trigger an event on a DOM element', () => { |
||||||
|
// https://on.cypress.io/trigger
|
||||||
|
|
||||||
|
// To interact with a range input (slider)
|
||||||
|
// we need to set its value & trigger the
|
||||||
|
// event to signal it changed
|
||||||
|
|
||||||
|
// Here, we invoke jQuery's val() method to set
|
||||||
|
// the value and trigger the 'change' event
|
||||||
|
cy.get('.trigger-input-range') |
||||||
|
.invoke('val', 25) |
||||||
|
.trigger('change') |
||||||
|
.get('input[type=range]').siblings('p') |
||||||
|
.should('have.text', '25') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.scrollTo() - scroll the window or element to a position', () => { |
||||||
|
// https://on.cypress.io/scrollto
|
||||||
|
|
||||||
|
// You can scroll to 9 specific positions of an element:
|
||||||
|
// -----------------------------------
|
||||||
|
// | topLeft top topRight |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | left center right |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | bottomLeft bottom bottomRight |
|
||||||
|
// -----------------------------------
|
||||||
|
|
||||||
|
// if you chain .scrollTo() off of cy, we will
|
||||||
|
// scroll the entire window
|
||||||
|
cy.scrollTo('bottom') |
||||||
|
|
||||||
|
cy.get('#scrollable-horizontal').scrollTo('right') |
||||||
|
|
||||||
|
// or you can scroll to a specific coordinate:
|
||||||
|
// (x axis, y axis) in pixels
|
||||||
|
cy.get('#scrollable-vertical').scrollTo(250, 250) |
||||||
|
|
||||||
|
// or you can scroll to a specific percentage
|
||||||
|
// of the (width, height) of the element
|
||||||
|
cy.get('#scrollable-both').scrollTo('75%', '25%') |
||||||
|
|
||||||
|
// control the easing of the scroll (default is 'swing')
|
||||||
|
cy.get('#scrollable-vertical').scrollTo('center', { easing: 'linear' }) |
||||||
|
|
||||||
|
// control the duration of the scroll (in ms)
|
||||||
|
cy.get('#scrollable-both').scrollTo('center', { duration: 2000 }) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,39 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Aliasing', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/commands/aliasing') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.as() - alias a DOM element for later use', () => { |
||||||
|
// https://on.cypress.io/as
|
||||||
|
|
||||||
|
// Alias a DOM element for use later
|
||||||
|
// We don't have to traverse to the element
|
||||||
|
// later in our code, we reference it with @
|
||||||
|
|
||||||
|
cy.get('.as-table').find('tbody>tr') |
||||||
|
.first().find('td').first() |
||||||
|
.find('button').as('firstBtn') |
||||||
|
|
||||||
|
// when we reference the alias, we place an
|
||||||
|
// @ in front of its name
|
||||||
|
cy.get('@firstBtn').click() |
||||||
|
|
||||||
|
cy.get('@firstBtn') |
||||||
|
.should('have.class', 'btn-success') |
||||||
|
.and('contain', 'Changed') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.as() - alias a route for later use', () => { |
||||||
|
// Alias the route to wait for its response
|
||||||
|
cy.intercept('GET', '**/comments/*').as('getComment') |
||||||
|
|
||||||
|
// we have code that gets a comment when
|
||||||
|
// the button is clicked in scripts.js
|
||||||
|
cy.get('.network-btn').click() |
||||||
|
|
||||||
|
// https://on.cypress.io/wait
|
||||||
|
cy.wait('@getComment').its('response.statusCode').should('eq', 200) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,176 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Assertions', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/commands/assertions') |
||||||
|
}) |
||||||
|
|
||||||
|
describe('Implicit Assertions', () => { |
||||||
|
it('.should() - make an assertion about the current subject', () => { |
||||||
|
// https://on.cypress.io/should
|
||||||
|
cy.get('.assertion-table') |
||||||
|
.find('tbody tr:last') |
||||||
|
.should('have.class', 'success') |
||||||
|
.find('td') |
||||||
|
.first() |
||||||
|
// checking the text of the <td> element in various ways
|
||||||
|
.should('have.text', 'Column content') |
||||||
|
.should('contain', 'Column content') |
||||||
|
.should('have.html', 'Column content') |
||||||
|
// chai-jquery uses "is()" to check if element matches selector
|
||||||
|
.should('match', 'td') |
||||||
|
// to match text content against a regular expression
|
||||||
|
// first need to invoke jQuery method text()
|
||||||
|
// and then match using regular expression
|
||||||
|
.invoke('text') |
||||||
|
.should('match', /column content/i) |
||||||
|
|
||||||
|
// a better way to check element's text content against a regular expression
|
||||||
|
// is to use "cy.contains"
|
||||||
|
// https://on.cypress.io/contains
|
||||||
|
cy.get('.assertion-table') |
||||||
|
.find('tbody tr:last') |
||||||
|
// finds first <td> element with text content matching regular expression
|
||||||
|
.contains('td', /column content/i) |
||||||
|
.should('be.visible') |
||||||
|
|
||||||
|
// for more information about asserting element's text
|
||||||
|
// see https://on.cypress.io/using-cypress-faq#How-do-I-get-an-element’s-text-contents
|
||||||
|
}) |
||||||
|
|
||||||
|
it('.and() - chain multiple assertions together', () => { |
||||||
|
// https://on.cypress.io/and
|
||||||
|
cy.get('.assertions-link') |
||||||
|
.should('have.class', 'active') |
||||||
|
.and('have.attr', 'href') |
||||||
|
.and('include', 'cypress.io') |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
describe('Explicit Assertions', () => { |
||||||
|
// https://on.cypress.io/assertions
|
||||||
|
it('expect - make an assertion about a specified subject', () => { |
||||||
|
// We can use Chai's BDD style assertions
|
||||||
|
expect(true).to.be.true |
||||||
|
const o = { foo: 'bar' } |
||||||
|
|
||||||
|
expect(o).to.equal(o) |
||||||
|
expect(o).to.deep.equal({ foo: 'bar' }) |
||||||
|
// matching text using regular expression
|
||||||
|
expect('FooBar').to.match(/bar$/i) |
||||||
|
}) |
||||||
|
|
||||||
|
it('pass your own callback function to should()', () => { |
||||||
|
// Pass a function to should that can have any number
|
||||||
|
// of explicit assertions within it.
|
||||||
|
// The ".should(cb)" function will be retried
|
||||||
|
// automatically until it passes all your explicit assertions or times out.
|
||||||
|
cy.get('.assertions-p') |
||||||
|
.find('p') |
||||||
|
.should(($p) => { |
||||||
|
// https://on.cypress.io/$
|
||||||
|
// return an array of texts from all of the p's
|
||||||
|
const texts = $p.map((i, el) => Cypress.$(el).text()) |
||||||
|
|
||||||
|
// jquery map returns jquery object
|
||||||
|
// and .get() convert this to simple array
|
||||||
|
const paragraphs = texts.get() |
||||||
|
|
||||||
|
// array should have length of 3
|
||||||
|
expect(paragraphs, 'has 3 paragraphs').to.have.length(3) |
||||||
|
|
||||||
|
// use second argument to expect(...) to provide clear
|
||||||
|
// message with each assertion
|
||||||
|
expect(paragraphs, 'has expected text in each paragraph').to.deep.eq([ |
||||||
|
'Some text from first p', |
||||||
|
'More text from second p', |
||||||
|
'And even more text from third p', |
||||||
|
]) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('finds element by class name regex', () => { |
||||||
|
cy.get('.docs-header') |
||||||
|
.find('div') |
||||||
|
// .should(cb) callback function will be retried
|
||||||
|
.should(($div) => { |
||||||
|
expect($div).to.have.length(1) |
||||||
|
|
||||||
|
const className = $div[0].className |
||||||
|
|
||||||
|
expect(className).to.match(/heading-/) |
||||||
|
}) |
||||||
|
// .then(cb) callback is not retried,
|
||||||
|
// it either passes or fails
|
||||||
|
.then(($div) => { |
||||||
|
expect($div, 'text content').to.have.text('Introduction') |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('can throw any error', () => { |
||||||
|
cy.get('.docs-header') |
||||||
|
.find('div') |
||||||
|
.should(($div) => { |
||||||
|
if ($div.length !== 1) { |
||||||
|
// you can throw your own errors
|
||||||
|
throw new Error('Did not find 1 element') |
||||||
|
} |
||||||
|
|
||||||
|
const className = $div[0].className |
||||||
|
|
||||||
|
if (!className.match(/heading-/)) { |
||||||
|
throw new Error(`Could not find class "heading-" in ${className}`) |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('matches unknown text between two elements', () => { |
||||||
|
/** |
||||||
|
* Text from the first element. |
||||||
|
* @type {string} |
||||||
|
*/ |
||||||
|
let text |
||||||
|
|
||||||
|
/** |
||||||
|
* Normalizes passed text, |
||||||
|
* useful before comparing text with spaces and different capitalization. |
||||||
|
* @param {string} s Text to normalize |
||||||
|
*/ |
||||||
|
const normalizeText = (s) => s.replace(/\s/g, '').toLowerCase() |
||||||
|
|
||||||
|
cy.get('.two-elements') |
||||||
|
.find('.first') |
||||||
|
.then(($first) => { |
||||||
|
// save text from the first element
|
||||||
|
text = normalizeText($first.text()) |
||||||
|
}) |
||||||
|
|
||||||
|
cy.get('.two-elements') |
||||||
|
.find('.second') |
||||||
|
.should(($div) => { |
||||||
|
// we can massage text before comparing
|
||||||
|
const secondText = normalizeText($div.text()) |
||||||
|
|
||||||
|
expect(secondText, 'second text').to.equal(text) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('assert - assert shape of an object', () => { |
||||||
|
const person = { |
||||||
|
name: 'Joe', |
||||||
|
age: 20, |
||||||
|
} |
||||||
|
|
||||||
|
assert.isObject(person, 'value is object') |
||||||
|
}) |
||||||
|
|
||||||
|
it('retries the should callback until assertions pass', () => { |
||||||
|
cy.get('#random-number') |
||||||
|
.should(($div) => { |
||||||
|
const n = parseFloat($div.text()) |
||||||
|
|
||||||
|
expect(n).to.be.gte(1).and.be.lte(10) |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,97 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Connectors', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/commands/connectors') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.each() - iterate over an array of elements', () => { |
||||||
|
// https://on.cypress.io/each
|
||||||
|
cy.get('.connectors-each-ul>li') |
||||||
|
.each(($el, index, $list) => { |
||||||
|
console.log($el, index, $list) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('.its() - get properties on the current subject', () => { |
||||||
|
// https://on.cypress.io/its
|
||||||
|
cy.get('.connectors-its-ul>li') |
||||||
|
// calls the 'length' property yielding that value
|
||||||
|
.its('length') |
||||||
|
.should('be.gt', 2) |
||||||
|
}) |
||||||
|
|
||||||
|
it('.invoke() - invoke a function on the current subject', () => { |
||||||
|
// our div is hidden in our script.js
|
||||||
|
// $('.connectors-div').hide()
|
||||||
|
|
||||||
|
// https://on.cypress.io/invoke
|
||||||
|
cy.get('.connectors-div').should('be.hidden') |
||||||
|
// call the jquery method 'show' on the 'div.container'
|
||||||
|
.invoke('show') |
||||||
|
.should('be.visible') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.spread() - spread an array as individual args to callback function', () => { |
||||||
|
// https://on.cypress.io/spread
|
||||||
|
const arr = ['foo', 'bar', 'baz'] |
||||||
|
|
||||||
|
cy.wrap(arr).spread((foo, bar, baz) => { |
||||||
|
expect(foo).to.eq('foo') |
||||||
|
expect(bar).to.eq('bar') |
||||||
|
expect(baz).to.eq('baz') |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
describe('.then()', () => { |
||||||
|
it('invokes a callback function with the current subject', () => { |
||||||
|
// https://on.cypress.io/then
|
||||||
|
cy.get('.connectors-list > li') |
||||||
|
.then(($lis) => { |
||||||
|
expect($lis, '3 items').to.have.length(3) |
||||||
|
expect($lis.eq(0), 'first item').to.contain('Walk the dog') |
||||||
|
expect($lis.eq(1), 'second item').to.contain('Feed the cat') |
||||||
|
expect($lis.eq(2), 'third item').to.contain('Write JavaScript') |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('yields the returned value to the next command', () => { |
||||||
|
cy.wrap(1) |
||||||
|
.then((num) => { |
||||||
|
expect(num).to.equal(1) |
||||||
|
|
||||||
|
return 2 |
||||||
|
}) |
||||||
|
.then((num) => { |
||||||
|
expect(num).to.equal(2) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('yields the original subject without return', () => { |
||||||
|
cy.wrap(1) |
||||||
|
.then((num) => { |
||||||
|
expect(num).to.equal(1) |
||||||
|
// note that nothing is returned from this callback
|
||||||
|
}) |
||||||
|
.then((num) => { |
||||||
|
// this callback receives the original unchanged value 1
|
||||||
|
expect(num).to.equal(1) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('yields the value yielded by the last Cypress command inside', () => { |
||||||
|
cy.wrap(1) |
||||||
|
.then((num) => { |
||||||
|
expect(num).to.equal(1) |
||||||
|
// note how we run a Cypress command
|
||||||
|
// the result yielded by this Cypress command
|
||||||
|
// will be passed to the second ".then"
|
||||||
|
cy.wrap(2) |
||||||
|
}) |
||||||
|
.then((num) => { |
||||||
|
// this callback receives the value yielded by "cy.wrap(2)"
|
||||||
|
expect(num).to.equal(2) |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,77 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Cookies', () => { |
||||||
|
beforeEach(() => { |
||||||
|
Cypress.Cookies.debug(true) |
||||||
|
|
||||||
|
cy.visit('https://example.cypress.io/commands/cookies') |
||||||
|
|
||||||
|
// clear cookies again after visiting to remove
|
||||||
|
// any 3rd party cookies picked up such as cloudflare
|
||||||
|
cy.clearCookies() |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.getCookie() - get a browser cookie', () => { |
||||||
|
// https://on.cypress.io/getcookie
|
||||||
|
cy.get('#getCookie .set-a-cookie').click() |
||||||
|
|
||||||
|
// cy.getCookie() yields a cookie object
|
||||||
|
cy.getCookie('token').should('have.property', 'value', '123ABC') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.getCookies() - get browser cookies', () => { |
||||||
|
// https://on.cypress.io/getcookies
|
||||||
|
cy.getCookies().should('be.empty') |
||||||
|
|
||||||
|
cy.get('#getCookies .set-a-cookie').click() |
||||||
|
|
||||||
|
// cy.getCookies() yields an array of cookies
|
||||||
|
cy.getCookies().should('have.length', 1).should((cookies) => { |
||||||
|
// each cookie has these properties
|
||||||
|
expect(cookies[0]).to.have.property('name', 'token') |
||||||
|
expect(cookies[0]).to.have.property('value', '123ABC') |
||||||
|
expect(cookies[0]).to.have.property('httpOnly', false) |
||||||
|
expect(cookies[0]).to.have.property('secure', false) |
||||||
|
expect(cookies[0]).to.have.property('domain') |
||||||
|
expect(cookies[0]).to.have.property('path') |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.setCookie() - set a browser cookie', () => { |
||||||
|
// https://on.cypress.io/setcookie
|
||||||
|
cy.getCookies().should('be.empty') |
||||||
|
|
||||||
|
cy.setCookie('foo', 'bar') |
||||||
|
|
||||||
|
// cy.getCookie() yields a cookie object
|
||||||
|
cy.getCookie('foo').should('have.property', 'value', 'bar') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.clearCookie() - clear a browser cookie', () => { |
||||||
|
// https://on.cypress.io/clearcookie
|
||||||
|
cy.getCookie('token').should('be.null') |
||||||
|
|
||||||
|
cy.get('#clearCookie .set-a-cookie').click() |
||||||
|
|
||||||
|
cy.getCookie('token').should('have.property', 'value', '123ABC') |
||||||
|
|
||||||
|
// cy.clearCookies() yields null
|
||||||
|
cy.clearCookie('token').should('be.null') |
||||||
|
|
||||||
|
cy.getCookie('token').should('be.null') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.clearCookies() - clear browser cookies', () => { |
||||||
|
// https://on.cypress.io/clearcookies
|
||||||
|
cy.getCookies().should('be.empty') |
||||||
|
|
||||||
|
cy.get('#clearCookies .set-a-cookie').click() |
||||||
|
|
||||||
|
cy.getCookies().should('have.length', 1) |
||||||
|
|
||||||
|
// cy.clearCookies() yields null
|
||||||
|
cy.clearCookies() |
||||||
|
|
||||||
|
cy.getCookies().should('be.empty') |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,200 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Cypress.Commands', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/cypress-api') |
||||||
|
}) |
||||||
|
|
||||||
|
// https://on.cypress.io/custom-commands
|
||||||
|
|
||||||
|
it('.add() - create a custom command', () => { |
||||||
|
Cypress.Commands.add('console', { |
||||||
|
prevSubject: true, |
||||||
|
}, (subject, method) => { |
||||||
|
// the previous subject is automatically received
|
||||||
|
// and the commands arguments are shifted
|
||||||
|
|
||||||
|
// allow us to change the console method used
|
||||||
|
method = method || 'log' |
||||||
|
|
||||||
|
// log the subject to the console
|
||||||
|
console[method]('The subject is', subject) |
||||||
|
|
||||||
|
// whatever we return becomes the new subject
|
||||||
|
// we don't want to change the subject so
|
||||||
|
// we return whatever was passed in
|
||||||
|
return subject |
||||||
|
}) |
||||||
|
|
||||||
|
cy.get('button').console('info').then(($button) => { |
||||||
|
// subject is still $button
|
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
context('Cypress.Cookies', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/cypress-api') |
||||||
|
}) |
||||||
|
|
||||||
|
// https://on.cypress.io/cookies
|
||||||
|
it('.debug() - enable or disable debugging', () => { |
||||||
|
Cypress.Cookies.debug(true) |
||||||
|
|
||||||
|
// Cypress will now log in the console when
|
||||||
|
// cookies are set or cleared
|
||||||
|
cy.setCookie('fakeCookie', '123ABC') |
||||||
|
cy.clearCookie('fakeCookie') |
||||||
|
cy.setCookie('fakeCookie', '123ABC') |
||||||
|
cy.clearCookie('fakeCookie') |
||||||
|
cy.setCookie('fakeCookie', '123ABC') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.preserveOnce() - preserve cookies by key', () => { |
||||||
|
// normally cookies are reset after each test
|
||||||
|
cy.getCookie('fakeCookie').should('not.be.ok') |
||||||
|
|
||||||
|
// preserving a cookie will not clear it when
|
||||||
|
// the next test starts
|
||||||
|
cy.setCookie('lastCookie', '789XYZ') |
||||||
|
Cypress.Cookies.preserveOnce('lastCookie') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.defaults() - set defaults for all cookies', () => { |
||||||
|
// now any cookie with the name 'session_id' will
|
||||||
|
// not be cleared before each new test runs
|
||||||
|
Cypress.Cookies.defaults({ |
||||||
|
preserve: 'session_id', |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
context('Cypress.arch', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/cypress-api') |
||||||
|
}) |
||||||
|
|
||||||
|
it('Get CPU architecture name of underlying OS', () => { |
||||||
|
// https://on.cypress.io/arch
|
||||||
|
expect(Cypress.arch).to.exist |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
context('Cypress.config()', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/cypress-api') |
||||||
|
}) |
||||||
|
|
||||||
|
it('Get and set configuration options', () => { |
||||||
|
// https://on.cypress.io/config
|
||||||
|
let myConfig = Cypress.config() |
||||||
|
|
||||||
|
expect(myConfig).to.have.property('animationDistanceThreshold', 5) |
||||||
|
expect(myConfig).to.have.property('baseUrl', null) |
||||||
|
expect(myConfig).to.have.property('defaultCommandTimeout', 4000) |
||||||
|
expect(myConfig).to.have.property('requestTimeout', 5000) |
||||||
|
expect(myConfig).to.have.property('responseTimeout', 30000) |
||||||
|
expect(myConfig).to.have.property('viewportHeight', 660) |
||||||
|
expect(myConfig).to.have.property('viewportWidth', 1000) |
||||||
|
expect(myConfig).to.have.property('pageLoadTimeout', 60000) |
||||||
|
expect(myConfig).to.have.property('waitForAnimations', true) |
||||||
|
|
||||||
|
expect(Cypress.config('pageLoadTimeout')).to.eq(60000) |
||||||
|
|
||||||
|
// this will change the config for the rest of your tests!
|
||||||
|
Cypress.config('pageLoadTimeout', 20000) |
||||||
|
|
||||||
|
expect(Cypress.config('pageLoadTimeout')).to.eq(20000) |
||||||
|
|
||||||
|
Cypress.config('pageLoadTimeout', 60000) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
context('Cypress.dom', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/cypress-api') |
||||||
|
}) |
||||||
|
|
||||||
|
// https://on.cypress.io/dom
|
||||||
|
it('.isHidden() - determine if a DOM element is hidden', () => { |
||||||
|
let hiddenP = Cypress.$('.dom-p p.hidden').get(0) |
||||||
|
let visibleP = Cypress.$('.dom-p p.visible').get(0) |
||||||
|
|
||||||
|
// our first paragraph has css class 'hidden'
|
||||||
|
expect(Cypress.dom.isHidden(hiddenP)).to.be.true |
||||||
|
expect(Cypress.dom.isHidden(visibleP)).to.be.false |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
context('Cypress.env()', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/cypress-api') |
||||||
|
}) |
||||||
|
|
||||||
|
// We can set environment variables for highly dynamic values
|
||||||
|
|
||||||
|
// https://on.cypress.io/environment-variables
|
||||||
|
it('Get environment variables', () => { |
||||||
|
// https://on.cypress.io/env
|
||||||
|
// set multiple environment variables
|
||||||
|
Cypress.env({ |
||||||
|
host: 'veronica.dev.local', |
||||||
|
api_server: 'http://localhost:8888/v1/', |
||||||
|
}) |
||||||
|
|
||||||
|
// get environment variable
|
||||||
|
expect(Cypress.env('host')).to.eq('veronica.dev.local') |
||||||
|
|
||||||
|
// set environment variable
|
||||||
|
Cypress.env('api_server', 'http://localhost:8888/v2/') |
||||||
|
expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/') |
||||||
|
|
||||||
|
// get all environment variable
|
||||||
|
expect(Cypress.env()).to.have.property('host', 'veronica.dev.local') |
||||||
|
expect(Cypress.env()).to.have.property('api_server', 'http://localhost:8888/v2/') |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
context('Cypress.log', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/cypress-api') |
||||||
|
}) |
||||||
|
|
||||||
|
it('Control what is printed to the Command Log', () => { |
||||||
|
// https://on.cypress.io/cypress-log
|
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
context('Cypress.platform', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/cypress-api') |
||||||
|
}) |
||||||
|
|
||||||
|
it('Get underlying OS name', () => { |
||||||
|
// https://on.cypress.io/platform
|
||||||
|
expect(Cypress.platform).to.be.exist |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
context('Cypress.version', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/cypress-api') |
||||||
|
}) |
||||||
|
|
||||||
|
it('Get current version of Cypress being run', () => { |
||||||
|
// https://on.cypress.io/version
|
||||||
|
expect(Cypress.version).to.be.exist |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
context('Cypress.spec', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/cypress-api') |
||||||
|
}) |
||||||
|
|
||||||
|
it('Get current spec information', () => { |
||||||
|
// https://on.cypress.io/spec
|
||||||
|
// wrap the object so we can inspect it easily by clicking in the command log
|
||||||
|
cy.wrap(Cypress.spec).should('include.keys', ['name', 'relative', 'absolute']) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,87 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
/// JSON fixture file can be loaded directly using
|
||||||
|
// the built-in JavaScript bundler
|
||||||
|
const requiredExample = require('../../fixtures/example') |
||||||
|
|
||||||
|
context('Files', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/commands/files') |
||||||
|
}) |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
// load example.json fixture file and store
|
||||||
|
// in the test context object
|
||||||
|
cy.fixture('example.json').as('example') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.fixture() - load a fixture', () => { |
||||||
|
// https://on.cypress.io/fixture
|
||||||
|
|
||||||
|
// Instead of writing a response inline you can
|
||||||
|
// use a fixture file's content.
|
||||||
|
|
||||||
|
// when application makes an Ajax request matching "GET **/comments/*"
|
||||||
|
// Cypress will intercept it and reply with the object in `example.json` fixture
|
||||||
|
cy.intercept('GET', '**/comments/*', { fixture: 'example.json' }).as('getComment') |
||||||
|
|
||||||
|
// we have code that gets a comment when
|
||||||
|
// the button is clicked in scripts.js
|
||||||
|
cy.get('.fixture-btn').click() |
||||||
|
|
||||||
|
cy.wait('@getComment').its('response.body') |
||||||
|
.should('have.property', 'name') |
||||||
|
.and('include', 'Using fixtures to represent data') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.fixture() or require - load a fixture', function () { |
||||||
|
// we are inside the "function () { ... }"
|
||||||
|
// callback and can use test context object "this"
|
||||||
|
// "this.example" was loaded in "beforeEach" function callback
|
||||||
|
expect(this.example, 'fixture in the test context') |
||||||
|
.to.deep.equal(requiredExample) |
||||||
|
|
||||||
|
// or use "cy.wrap" and "should('deep.equal', ...)" assertion
|
||||||
|
cy.wrap(this.example) |
||||||
|
.should('deep.equal', requiredExample) |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.readFile() - read file contents', () => { |
||||||
|
// https://on.cypress.io/readfile
|
||||||
|
|
||||||
|
// You can read a file and yield its contents
|
||||||
|
// The filePath is relative to your project's root.
|
||||||
|
cy.readFile(Cypress.config('configFile')).then((config) => { |
||||||
|
expect(config).to.be.an('string') |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.writeFile() - write to a file', () => { |
||||||
|
// https://on.cypress.io/writefile
|
||||||
|
|
||||||
|
// You can write to a file
|
||||||
|
|
||||||
|
// Use a response from a request to automatically
|
||||||
|
// generate a fixture file for use later
|
||||||
|
cy.request('https://jsonplaceholder.cypress.io/users') |
||||||
|
.then((response) => { |
||||||
|
cy.writeFile('cypress/fixtures/users.json', response.body) |
||||||
|
}) |
||||||
|
|
||||||
|
cy.fixture('users').should((users) => { |
||||||
|
expect(users[0].name).to.exist |
||||||
|
}) |
||||||
|
|
||||||
|
// JavaScript arrays and objects are stringified
|
||||||
|
// and formatted into text.
|
||||||
|
cy.writeFile('cypress/fixtures/profile.json', { |
||||||
|
id: 8739, |
||||||
|
name: 'Jane', |
||||||
|
email: 'jane@example.com', |
||||||
|
}) |
||||||
|
|
||||||
|
cy.fixture('profile').should((profile) => { |
||||||
|
expect(profile.name).to.eq('Jane') |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,52 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Local Storage', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/commands/local-storage') |
||||||
|
}) |
||||||
|
// Although local storage is automatically cleared
|
||||||
|
// in between tests to maintain a clean state
|
||||||
|
// sometimes we need to clear the local storage manually
|
||||||
|
|
||||||
|
it('cy.clearLocalStorage() - clear all data in local storage', () => { |
||||||
|
// https://on.cypress.io/clearlocalstorage
|
||||||
|
cy.get('.ls-btn').click().should(() => { |
||||||
|
expect(localStorage.getItem('prop1')).to.eq('red') |
||||||
|
expect(localStorage.getItem('prop2')).to.eq('blue') |
||||||
|
expect(localStorage.getItem('prop3')).to.eq('magenta') |
||||||
|
}) |
||||||
|
|
||||||
|
// clearLocalStorage() yields the localStorage object
|
||||||
|
cy.clearLocalStorage().should((ls) => { |
||||||
|
expect(ls.getItem('prop1')).to.be.null |
||||||
|
expect(ls.getItem('prop2')).to.be.null |
||||||
|
expect(ls.getItem('prop3')).to.be.null |
||||||
|
}) |
||||||
|
|
||||||
|
cy.get('.ls-btn').click().should(() => { |
||||||
|
expect(localStorage.getItem('prop1')).to.eq('red') |
||||||
|
expect(localStorage.getItem('prop2')).to.eq('blue') |
||||||
|
expect(localStorage.getItem('prop3')).to.eq('magenta') |
||||||
|
}) |
||||||
|
|
||||||
|
// Clear key matching string in Local Storage
|
||||||
|
cy.clearLocalStorage('prop1').should((ls) => { |
||||||
|
expect(ls.getItem('prop1')).to.be.null |
||||||
|
expect(ls.getItem('prop2')).to.eq('blue') |
||||||
|
expect(ls.getItem('prop3')).to.eq('magenta') |
||||||
|
}) |
||||||
|
|
||||||
|
cy.get('.ls-btn').click().should(() => { |
||||||
|
expect(localStorage.getItem('prop1')).to.eq('red') |
||||||
|
expect(localStorage.getItem('prop2')).to.eq('blue') |
||||||
|
expect(localStorage.getItem('prop3')).to.eq('magenta') |
||||||
|
}) |
||||||
|
|
||||||
|
// Clear keys matching regex in Local Storage
|
||||||
|
cy.clearLocalStorage(/prop1|2/).should((ls) => { |
||||||
|
expect(ls.getItem('prop1')).to.be.null |
||||||
|
expect(ls.getItem('prop2')).to.be.null |
||||||
|
expect(ls.getItem('prop3')).to.eq('magenta') |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,32 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Location', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/commands/location') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.hash() - get the current URL hash', () => { |
||||||
|
// https://on.cypress.io/hash
|
||||||
|
cy.hash().should('be.empty') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.location() - get window.location', () => { |
||||||
|
// https://on.cypress.io/location
|
||||||
|
cy.location().should((location) => { |
||||||
|
expect(location.hash).to.be.empty |
||||||
|
expect(location.href).to.eq('https://example.cypress.io/commands/location') |
||||||
|
expect(location.host).to.eq('example.cypress.io') |
||||||
|
expect(location.hostname).to.eq('example.cypress.io') |
||||||
|
expect(location.origin).to.eq('https://example.cypress.io') |
||||||
|
expect(location.pathname).to.eq('/commands/location') |
||||||
|
expect(location.port).to.eq('') |
||||||
|
expect(location.protocol).to.eq('https:') |
||||||
|
expect(location.search).to.be.empty |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.url() - get the current URL', () => { |
||||||
|
// https://on.cypress.io/url
|
||||||
|
cy.url().should('eq', 'https://example.cypress.io/commands/location') |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,104 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Misc', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/commands/misc') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.end() - end the command chain', () => { |
||||||
|
// https://on.cypress.io/end
|
||||||
|
|
||||||
|
// cy.end is useful when you want to end a chain of commands
|
||||||
|
// and force Cypress to re-query from the root element
|
||||||
|
cy.get('.misc-table').within(() => { |
||||||
|
// ends the current chain and yields null
|
||||||
|
cy.contains('Cheryl').click().end() |
||||||
|
|
||||||
|
// queries the entire table again
|
||||||
|
cy.contains('Charles').click() |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.exec() - execute a system command', () => { |
||||||
|
// execute a system command.
|
||||||
|
// so you can take actions necessary for
|
||||||
|
// your test outside the scope of Cypress.
|
||||||
|
// https://on.cypress.io/exec
|
||||||
|
|
||||||
|
// we can use Cypress.platform string to
|
||||||
|
// select appropriate command
|
||||||
|
// https://on.cypress/io/platform
|
||||||
|
cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`) |
||||||
|
|
||||||
|
// on CircleCI Windows build machines we have a failure to run bash shell
|
||||||
|
// https://github.com/cypress-io/cypress/issues/5169
|
||||||
|
// so skip some of the tests by passing flag "--env circle=true"
|
||||||
|
const isCircleOnWindows = Cypress.platform === 'win32' && Cypress.env('circle') |
||||||
|
|
||||||
|
if (isCircleOnWindows) { |
||||||
|
cy.log('Skipping test on CircleCI') |
||||||
|
|
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// cy.exec problem on Shippable CI
|
||||||
|
// https://github.com/cypress-io/cypress/issues/6718
|
||||||
|
const isShippable = Cypress.platform === 'linux' && Cypress.env('shippable') |
||||||
|
|
||||||
|
if (isShippable) { |
||||||
|
cy.log('Skipping test on ShippableCI') |
||||||
|
|
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
cy.exec('echo Jane Lane') |
||||||
|
.its('stdout').should('contain', 'Jane Lane') |
||||||
|
|
||||||
|
if (Cypress.platform === 'win32') { |
||||||
|
cy.exec(`print ${Cypress.config('configFile')}`) |
||||||
|
.its('stderr').should('be.empty') |
||||||
|
} else { |
||||||
|
cy.exec(`cat ${Cypress.config('configFile')}`) |
||||||
|
.its('stderr').should('be.empty') |
||||||
|
|
||||||
|
cy.exec('pwd') |
||||||
|
.its('code').should('eq', 0) |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.focused() - get the DOM element that has focus', () => { |
||||||
|
// https://on.cypress.io/focused
|
||||||
|
cy.get('.misc-form').find('#name').click() |
||||||
|
cy.focused().should('have.id', 'name') |
||||||
|
|
||||||
|
cy.get('.misc-form').find('#description').click() |
||||||
|
cy.focused().should('have.id', 'description') |
||||||
|
}) |
||||||
|
|
||||||
|
context('Cypress.Screenshot', function () { |
||||||
|
it('cy.screenshot() - take a screenshot', () => { |
||||||
|
// https://on.cypress.io/screenshot
|
||||||
|
cy.screenshot('my-image') |
||||||
|
}) |
||||||
|
|
||||||
|
it('Cypress.Screenshot.defaults() - change default config of screenshots', function () { |
||||||
|
Cypress.Screenshot.defaults({ |
||||||
|
blackout: ['.foo'], |
||||||
|
capture: 'viewport', |
||||||
|
clip: { x: 0, y: 0, width: 200, height: 200 }, |
||||||
|
scale: false, |
||||||
|
disableTimersAndAnimations: true, |
||||||
|
screenshotOnRunFailure: true, |
||||||
|
onBeforeScreenshot () { }, |
||||||
|
onAfterScreenshot () { }, |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.wrap() - wrap an object', () => { |
||||||
|
// https://on.cypress.io/wrap
|
||||||
|
cy.wrap({ foo: 'bar' }) |
||||||
|
.should('have.property', 'foo') |
||||||
|
.and('include', 'bar') |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,56 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Navigation', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io') |
||||||
|
cy.get('.navbar-nav').contains('Commands').click() |
||||||
|
cy.get('.dropdown-menu').contains('Navigation').click() |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.go() - go back or forward in the browser\'s history', () => { |
||||||
|
// https://on.cypress.io/go
|
||||||
|
|
||||||
|
cy.location('pathname').should('include', 'navigation') |
||||||
|
|
||||||
|
cy.go('back') |
||||||
|
cy.location('pathname').should('not.include', 'navigation') |
||||||
|
|
||||||
|
cy.go('forward') |
||||||
|
cy.location('pathname').should('include', 'navigation') |
||||||
|
|
||||||
|
// clicking back
|
||||||
|
cy.go(-1) |
||||||
|
cy.location('pathname').should('not.include', 'navigation') |
||||||
|
|
||||||
|
// clicking forward
|
||||||
|
cy.go(1) |
||||||
|
cy.location('pathname').should('include', 'navigation') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.reload() - reload the page', () => { |
||||||
|
// https://on.cypress.io/reload
|
||||||
|
cy.reload() |
||||||
|
|
||||||
|
// reload the page without using the cache
|
||||||
|
cy.reload(true) |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.visit() - visit a remote url', () => { |
||||||
|
// https://on.cypress.io/visit
|
||||||
|
|
||||||
|
// Visit any sub-domain of your current domain
|
||||||
|
|
||||||
|
// Pass options to the visit
|
||||||
|
cy.visit('https://example.cypress.io/commands/navigation', { |
||||||
|
timeout: 50000, // increase total time for the visit to resolve
|
||||||
|
onBeforeLoad (contentWindow) { |
||||||
|
// contentWindow is the remote page's window object
|
||||||
|
expect(typeof contentWindow === 'object').to.be.true |
||||||
|
}, |
||||||
|
onLoad (contentWindow) { |
||||||
|
// contentWindow is the remote page's window object
|
||||||
|
expect(typeof contentWindow === 'object').to.be.true |
||||||
|
}, |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,163 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Network Requests', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/commands/network-requests') |
||||||
|
}) |
||||||
|
|
||||||
|
// Manage HTTP requests in your app
|
||||||
|
|
||||||
|
it('cy.request() - make an XHR request', () => { |
||||||
|
// https://on.cypress.io/request
|
||||||
|
cy.request('https://jsonplaceholder.cypress.io/comments') |
||||||
|
.should((response) => { |
||||||
|
expect(response.status).to.eq(200) |
||||||
|
// the server sometimes gets an extra comment posted from another machine
|
||||||
|
// which gets returned as 1 extra object
|
||||||
|
expect(response.body).to.have.property('length').and.be.oneOf([500, 501]) |
||||||
|
expect(response).to.have.property('headers') |
||||||
|
expect(response).to.have.property('duration') |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.request() - verify response using BDD syntax', () => { |
||||||
|
cy.request('https://jsonplaceholder.cypress.io/comments') |
||||||
|
.then((response) => { |
||||||
|
// https://on.cypress.io/assertions
|
||||||
|
expect(response).property('status').to.equal(200) |
||||||
|
expect(response).property('body').to.have.property('length').and.be.oneOf([500, 501]) |
||||||
|
expect(response).to.include.keys('headers', 'duration') |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.request() with query parameters', () => { |
||||||
|
// will execute request
|
||||||
|
// https://jsonplaceholder.cypress.io/comments?postId=1&id=3
|
||||||
|
cy.request({ |
||||||
|
url: 'https://jsonplaceholder.cypress.io/comments', |
||||||
|
qs: { |
||||||
|
postId: 1, |
||||||
|
id: 3, |
||||||
|
}, |
||||||
|
}) |
||||||
|
.its('body') |
||||||
|
.should('be.an', 'array') |
||||||
|
.and('have.length', 1) |
||||||
|
.its('0') // yields first element of the array
|
||||||
|
.should('contain', { |
||||||
|
postId: 1, |
||||||
|
id: 3, |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.request() - pass result to the second request', () => { |
||||||
|
// first, let's find out the userId of the first user we have
|
||||||
|
cy.request('https://jsonplaceholder.cypress.io/users?_limit=1') |
||||||
|
.its('body') // yields the response object
|
||||||
|
.its('0') // yields the first element of the returned list
|
||||||
|
// the above two commands its('body').its('0')
|
||||||
|
// can be written as its('body.0')
|
||||||
|
// if you do not care about TypeScript checks
|
||||||
|
.then((user) => { |
||||||
|
expect(user).property('id').to.be.a('number') |
||||||
|
// make a new post on behalf of the user
|
||||||
|
cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', { |
||||||
|
userId: user.id, |
||||||
|
title: 'Cypress Test Runner', |
||||||
|
body: 'Fast, easy and reliable testing for anything that runs in a browser.', |
||||||
|
}) |
||||||
|
}) |
||||||
|
// note that the value here is the returned value of the 2nd request
|
||||||
|
// which is the new post object
|
||||||
|
.then((response) => { |
||||||
|
expect(response).property('status').to.equal(201) // new entity created
|
||||||
|
expect(response).property('body').to.contain({ |
||||||
|
title: 'Cypress Test Runner', |
||||||
|
}) |
||||||
|
|
||||||
|
// we don't know the exact post id - only that it will be > 100
|
||||||
|
// since JSONPlaceholder has built-in 100 posts
|
||||||
|
expect(response.body).property('id').to.be.a('number') |
||||||
|
.and.to.be.gt(100) |
||||||
|
|
||||||
|
// we don't know the user id here - since it was in above closure
|
||||||
|
// so in this test just confirm that the property is there
|
||||||
|
expect(response.body).property('userId').to.be.a('number') |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.request() - save response in the shared test context', () => { |
||||||
|
// https://on.cypress.io/variables-and-aliases
|
||||||
|
cy.request('https://jsonplaceholder.cypress.io/users?_limit=1') |
||||||
|
.its('body').its('0') // yields the first element of the returned list
|
||||||
|
.as('user') // saves the object in the test context
|
||||||
|
.then(function () { |
||||||
|
// NOTE 👀
|
||||||
|
// By the time this callback runs the "as('user')" command
|
||||||
|
// has saved the user object in the test context.
|
||||||
|
// To access the test context we need to use
|
||||||
|
// the "function () { ... }" callback form,
|
||||||
|
// otherwise "this" points at a wrong or undefined object!
|
||||||
|
cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', { |
||||||
|
userId: this.user.id, |
||||||
|
title: 'Cypress Test Runner', |
||||||
|
body: 'Fast, easy and reliable testing for anything that runs in a browser.', |
||||||
|
}) |
||||||
|
.its('body').as('post') // save the new post from the response
|
||||||
|
}) |
||||||
|
.then(function () { |
||||||
|
// When this callback runs, both "cy.request" API commands have finished
|
||||||
|
// and the test context has "user" and "post" objects set.
|
||||||
|
// Let's verify them.
|
||||||
|
expect(this.post, 'post has the right user id').property('userId').to.equal(this.user.id) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.intercept() - route responses to matching requests', () => { |
||||||
|
// https://on.cypress.io/intercept
|
||||||
|
|
||||||
|
let message = 'whoa, this comment does not exist' |
||||||
|
|
||||||
|
// Listen to GET to comments/1
|
||||||
|
cy.intercept('GET', '**/comments/*').as('getComment') |
||||||
|
|
||||||
|
// we have code that gets a comment when
|
||||||
|
// the button is clicked in scripts.js
|
||||||
|
cy.get('.network-btn').click() |
||||||
|
|
||||||
|
// https://on.cypress.io/wait
|
||||||
|
cy.wait('@getComment').its('response.statusCode').should('be.oneOf', [200, 304]) |
||||||
|
|
||||||
|
// Listen to POST to comments
|
||||||
|
cy.intercept('POST', '**/comments').as('postComment') |
||||||
|
|
||||||
|
// we have code that posts a comment when
|
||||||
|
// the button is clicked in scripts.js
|
||||||
|
cy.get('.network-post').click() |
||||||
|
cy.wait('@postComment').should(({ request, response }) => { |
||||||
|
expect(request.body).to.include('email') |
||||||
|
expect(request.headers).to.have.property('content-type') |
||||||
|
expect(response && response.body).to.have.property('name', 'Using POST in cy.intercept()') |
||||||
|
}) |
||||||
|
|
||||||
|
// Stub a response to PUT comments/ ****
|
||||||
|
cy.intercept({ |
||||||
|
method: 'PUT', |
||||||
|
url: '**/comments/*', |
||||||
|
}, { |
||||||
|
statusCode: 404, |
||||||
|
body: { error: message }, |
||||||
|
headers: { 'access-control-allow-origin': '*' }, |
||||||
|
delayMs: 500, |
||||||
|
}).as('putComment') |
||||||
|
|
||||||
|
// we have code that puts a comment when
|
||||||
|
// the button is clicked in scripts.js
|
||||||
|
cy.get('.network-put').click() |
||||||
|
|
||||||
|
cy.wait('@putComment') |
||||||
|
|
||||||
|
// our 404 statusCode logic in scripts.js executed
|
||||||
|
cy.get('.network-put-comment').should('contain', message) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,114 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Querying', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/commands/querying') |
||||||
|
}) |
||||||
|
|
||||||
|
// The most commonly used query is 'cy.get()', you can
|
||||||
|
// think of this like the '$' in jQuery
|
||||||
|
|
||||||
|
it('cy.get() - query DOM elements', () => { |
||||||
|
// https://on.cypress.io/get
|
||||||
|
|
||||||
|
cy.get('#query-btn').should('contain', 'Button') |
||||||
|
|
||||||
|
cy.get('.query-btn').should('contain', 'Button') |
||||||
|
|
||||||
|
cy.get('#querying .well>button:first').should('contain', 'Button') |
||||||
|
// ↲
|
||||||
|
// Use CSS selectors just like jQuery
|
||||||
|
|
||||||
|
cy.get('[data-test-id="test-example"]').should('have.class', 'example') |
||||||
|
|
||||||
|
// 'cy.get()' yields jQuery object, you can get its attribute
|
||||||
|
// by invoking `.attr()` method
|
||||||
|
cy.get('[data-test-id="test-example"]') |
||||||
|
.invoke('attr', 'data-test-id') |
||||||
|
.should('equal', 'test-example') |
||||||
|
|
||||||
|
// or you can get element's CSS property
|
||||||
|
cy.get('[data-test-id="test-example"]') |
||||||
|
.invoke('css', 'position') |
||||||
|
.should('equal', 'static') |
||||||
|
|
||||||
|
// or use assertions directly during 'cy.get()'
|
||||||
|
// https://on.cypress.io/assertions
|
||||||
|
cy.get('[data-test-id="test-example"]') |
||||||
|
.should('have.attr', 'data-test-id', 'test-example') |
||||||
|
.and('have.css', 'position', 'static') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.contains() - query DOM elements with matching content', () => { |
||||||
|
// https://on.cypress.io/contains
|
||||||
|
cy.get('.query-list') |
||||||
|
.contains('bananas') |
||||||
|
.should('have.class', 'third') |
||||||
|
|
||||||
|
// we can pass a regexp to `.contains()`
|
||||||
|
cy.get('.query-list') |
||||||
|
.contains(/^b\w+/) |
||||||
|
.should('have.class', 'third') |
||||||
|
|
||||||
|
cy.get('.query-list') |
||||||
|
.contains('apples') |
||||||
|
.should('have.class', 'first') |
||||||
|
|
||||||
|
// passing a selector to contains will
|
||||||
|
// yield the selector containing the text
|
||||||
|
cy.get('#querying') |
||||||
|
.contains('ul', 'oranges') |
||||||
|
.should('have.class', 'query-list') |
||||||
|
|
||||||
|
cy.get('.query-button') |
||||||
|
.contains('Save Form') |
||||||
|
.should('have.class', 'btn') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.within() - query DOM elements within a specific element', () => { |
||||||
|
// https://on.cypress.io/within
|
||||||
|
cy.get('.query-form').within(() => { |
||||||
|
cy.get('input:first').should('have.attr', 'placeholder', 'Email') |
||||||
|
cy.get('input:last').should('have.attr', 'placeholder', 'Password') |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.root() - query the root DOM element', () => { |
||||||
|
// https://on.cypress.io/root
|
||||||
|
|
||||||
|
// By default, root is the document
|
||||||
|
cy.root().should('match', 'html') |
||||||
|
|
||||||
|
cy.get('.query-ul').within(() => { |
||||||
|
// In this within, the root is now the ul DOM element
|
||||||
|
cy.root().should('have.class', 'query-ul') |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('best practices - selecting elements', () => { |
||||||
|
// https://on.cypress.io/best-practices#Selecting-Elements
|
||||||
|
cy.get('[data-cy=best-practices-selecting-elements]').within(() => { |
||||||
|
// Worst - too generic, no context
|
||||||
|
cy.get('button').click() |
||||||
|
|
||||||
|
// Bad. Coupled to styling. Highly subject to change.
|
||||||
|
cy.get('.btn.btn-large').click() |
||||||
|
|
||||||
|
// Average. Coupled to the `name` attribute which has HTML semantics.
|
||||||
|
cy.get('[name=submission]').click() |
||||||
|
|
||||||
|
// Better. But still coupled to styling or JS event listeners.
|
||||||
|
cy.get('#main').click() |
||||||
|
|
||||||
|
// Slightly better. Uses an ID but also ensures the element
|
||||||
|
// has an ARIA role attribute
|
||||||
|
cy.get('#main[role=button]').click() |
||||||
|
|
||||||
|
// Much better. But still coupled to text content that may change.
|
||||||
|
cy.contains('Submit').click() |
||||||
|
|
||||||
|
// Best. Insulated from all changes.
|
||||||
|
cy.get('[data-cy=submit]').click() |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,203 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
// remove no check once Cypress.sinon is typed
|
||||||
|
// https://github.com/cypress-io/cypress/issues/6720
|
||||||
|
|
||||||
|
context('Spies, Stubs, and Clock', () => { |
||||||
|
it('cy.spy() - wrap a method in a spy', () => { |
||||||
|
// https://on.cypress.io/spy
|
||||||
|
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks') |
||||||
|
|
||||||
|
const obj = { |
||||||
|
foo () {}, |
||||||
|
} |
||||||
|
|
||||||
|
const spy = cy.spy(obj, 'foo').as('anyArgs') |
||||||
|
|
||||||
|
obj.foo() |
||||||
|
|
||||||
|
expect(spy).to.be.called |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.spy() retries until assertions pass', () => { |
||||||
|
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks') |
||||||
|
|
||||||
|
const obj = { |
||||||
|
/** |
||||||
|
* Prints the argument passed |
||||||
|
* @param x {any} |
||||||
|
*/ |
||||||
|
foo (x) { |
||||||
|
console.log('obj.foo called with', x) |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
cy.spy(obj, 'foo').as('foo') |
||||||
|
|
||||||
|
setTimeout(() => { |
||||||
|
obj.foo('first') |
||||||
|
}, 500) |
||||||
|
|
||||||
|
setTimeout(() => { |
||||||
|
obj.foo('second') |
||||||
|
}, 2500) |
||||||
|
|
||||||
|
cy.get('@foo').should('have.been.calledTwice') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.stub() - create a stub and/or replace a function with stub', () => { |
||||||
|
// https://on.cypress.io/stub
|
||||||
|
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks') |
||||||
|
|
||||||
|
const obj = { |
||||||
|
/** |
||||||
|
* prints both arguments to the console |
||||||
|
* @param a {string} |
||||||
|
* @param b {string} |
||||||
|
*/ |
||||||
|
foo (a, b) { |
||||||
|
console.log('a', a, 'b', b) |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
const stub = cy.stub(obj, 'foo').as('foo') |
||||||
|
|
||||||
|
obj.foo('foo', 'bar') |
||||||
|
|
||||||
|
expect(stub).to.be.called |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.clock() - control time in the browser', () => { |
||||||
|
// https://on.cypress.io/clock
|
||||||
|
|
||||||
|
// create the date in UTC so its always the same
|
||||||
|
// no matter what local timezone the browser is running in
|
||||||
|
const now = new Date(Date.UTC(2017, 2, 14)).getTime() |
||||||
|
|
||||||
|
cy.clock(now) |
||||||
|
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks') |
||||||
|
cy.get('#clock-div').click() |
||||||
|
.should('have.text', '1489449600') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.tick() - move time in the browser', () => { |
||||||
|
// https://on.cypress.io/tick
|
||||||
|
|
||||||
|
// create the date in UTC so its always the same
|
||||||
|
// no matter what local timezone the browser is running in
|
||||||
|
const now = new Date(Date.UTC(2017, 2, 14)).getTime() |
||||||
|
|
||||||
|
cy.clock(now) |
||||||
|
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks') |
||||||
|
cy.get('#tick-div').click() |
||||||
|
.should('have.text', '1489449600') |
||||||
|
|
||||||
|
cy.tick(10000) // 10 seconds passed
|
||||||
|
cy.get('#tick-div').click() |
||||||
|
.should('have.text', '1489449610') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.stub() matches depending on arguments', () => { |
||||||
|
// see all possible matchers at
|
||||||
|
// https://sinonjs.org/releases/latest/matchers/
|
||||||
|
const greeter = { |
||||||
|
/** |
||||||
|
* Greets a person |
||||||
|
* @param {string} name |
||||||
|
*/ |
||||||
|
greet (name) { |
||||||
|
return `Hello, ${name}!` |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
cy.stub(greeter, 'greet') |
||||||
|
.callThrough() // if you want non-matched calls to call the real method
|
||||||
|
.withArgs(Cypress.sinon.match.string).returns('Hi') |
||||||
|
.withArgs(Cypress.sinon.match.number).throws(new Error('Invalid name')) |
||||||
|
|
||||||
|
expect(greeter.greet('World')).to.equal('Hi') |
||||||
|
expect(() => greeter.greet(42)).to.throw('Invalid name') |
||||||
|
expect(greeter.greet).to.have.been.calledTwice |
||||||
|
|
||||||
|
// non-matched calls goes the actual method
|
||||||
|
expect(greeter.greet()).to.equal('Hello, undefined!') |
||||||
|
}) |
||||||
|
|
||||||
|
it('matches call arguments using Sinon matchers', () => { |
||||||
|
// see all possible matchers at
|
||||||
|
// https://sinonjs.org/releases/latest/matchers/
|
||||||
|
const calculator = { |
||||||
|
/** |
||||||
|
* returns the sum of two arguments |
||||||
|
* @param a {number} |
||||||
|
* @param b {number} |
||||||
|
*/ |
||||||
|
add (a, b) { |
||||||
|
return a + b |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
const spy = cy.spy(calculator, 'add').as('add') |
||||||
|
|
||||||
|
expect(calculator.add(2, 3)).to.equal(5) |
||||||
|
|
||||||
|
// if we want to assert the exact values used during the call
|
||||||
|
expect(spy).to.be.calledWith(2, 3) |
||||||
|
|
||||||
|
// let's confirm "add" method was called with two numbers
|
||||||
|
expect(spy).to.be.calledWith(Cypress.sinon.match.number, Cypress.sinon.match.number) |
||||||
|
|
||||||
|
// alternatively, provide the value to match
|
||||||
|
expect(spy).to.be.calledWith(Cypress.sinon.match(2), Cypress.sinon.match(3)) |
||||||
|
|
||||||
|
// match any value
|
||||||
|
expect(spy).to.be.calledWith(Cypress.sinon.match.any, 3) |
||||||
|
|
||||||
|
// match any value from a list
|
||||||
|
expect(spy).to.be.calledWith(Cypress.sinon.match.in([1, 2, 3]), 3) |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns true if the given number is even |
||||||
|
* @param {number} x |
||||||
|
*/ |
||||||
|
const isEven = (x) => x % 2 === 0 |
||||||
|
|
||||||
|
// expect the value to pass a custom predicate function
|
||||||
|
// the second argument to "sinon.match(predicate, message)" is
|
||||||
|
// shown if the predicate does not pass and assertion fails
|
||||||
|
expect(spy).to.be.calledWith(Cypress.sinon.match(isEven, 'isEven'), 3) |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns a function that checks if a given number is larger than the limit |
||||||
|
* @param {number} limit |
||||||
|
* @returns {(x: number) => boolean} |
||||||
|
*/ |
||||||
|
const isGreaterThan = (limit) => (x) => x > limit |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns a function that checks if a given number is less than the limit |
||||||
|
* @param {number} limit |
||||||
|
* @returns {(x: number) => boolean} |
||||||
|
*/ |
||||||
|
const isLessThan = (limit) => (x) => x < limit |
||||||
|
|
||||||
|
// you can combine several matchers using "and", "or"
|
||||||
|
expect(spy).to.be.calledWith( |
||||||
|
Cypress.sinon.match.number, |
||||||
|
Cypress.sinon.match(isGreaterThan(2), '> 2').and(Cypress.sinon.match(isLessThan(4), '< 4')), |
||||||
|
) |
||||||
|
|
||||||
|
expect(spy).to.be.calledWith( |
||||||
|
Cypress.sinon.match.number, |
||||||
|
Cypress.sinon.match(isGreaterThan(200), '> 200').or(Cypress.sinon.match(3)), |
||||||
|
) |
||||||
|
|
||||||
|
// matchers can be used from BDD assertions
|
||||||
|
cy.get('@add').should('have.been.calledWith', |
||||||
|
Cypress.sinon.match.number, Cypress.sinon.match(3)) |
||||||
|
|
||||||
|
// you can alias matchers for shorter test code
|
||||||
|
const { match: M } = Cypress.sinon |
||||||
|
|
||||||
|
cy.get('@add').should('have.been.calledWith', M.number, M(3)) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,121 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Traversal', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/commands/traversal') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.children() - get child DOM elements', () => { |
||||||
|
// https://on.cypress.io/children
|
||||||
|
cy.get('.traversal-breadcrumb') |
||||||
|
.children('.active') |
||||||
|
.should('contain', 'Data') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.closest() - get closest ancestor DOM element', () => { |
||||||
|
// https://on.cypress.io/closest
|
||||||
|
cy.get('.traversal-badge') |
||||||
|
.closest('ul') |
||||||
|
.should('have.class', 'list-group') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.eq() - get a DOM element at a specific index', () => { |
||||||
|
// https://on.cypress.io/eq
|
||||||
|
cy.get('.traversal-list>li') |
||||||
|
.eq(1).should('contain', 'siamese') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.filter() - get DOM elements that match the selector', () => { |
||||||
|
// https://on.cypress.io/filter
|
||||||
|
cy.get('.traversal-nav>li') |
||||||
|
.filter('.active').should('contain', 'About') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.find() - get descendant DOM elements of the selector', () => { |
||||||
|
// https://on.cypress.io/find
|
||||||
|
cy.get('.traversal-pagination') |
||||||
|
.find('li').find('a') |
||||||
|
.should('have.length', 7) |
||||||
|
}) |
||||||
|
|
||||||
|
it('.first() - get first DOM element', () => { |
||||||
|
// https://on.cypress.io/first
|
||||||
|
cy.get('.traversal-table td') |
||||||
|
.first().should('contain', '1') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.last() - get last DOM element', () => { |
||||||
|
// https://on.cypress.io/last
|
||||||
|
cy.get('.traversal-buttons .btn') |
||||||
|
.last().should('contain', 'Submit') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.next() - get next sibling DOM element', () => { |
||||||
|
// https://on.cypress.io/next
|
||||||
|
cy.get('.traversal-ul') |
||||||
|
.contains('apples').next().should('contain', 'oranges') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.nextAll() - get all next sibling DOM elements', () => { |
||||||
|
// https://on.cypress.io/nextall
|
||||||
|
cy.get('.traversal-next-all') |
||||||
|
.contains('oranges') |
||||||
|
.nextAll().should('have.length', 3) |
||||||
|
}) |
||||||
|
|
||||||
|
it('.nextUntil() - get next sibling DOM elements until next el', () => { |
||||||
|
// https://on.cypress.io/nextuntil
|
||||||
|
cy.get('#veggies') |
||||||
|
.nextUntil('#nuts').should('have.length', 3) |
||||||
|
}) |
||||||
|
|
||||||
|
it('.not() - remove DOM elements from set of DOM elements', () => { |
||||||
|
// https://on.cypress.io/not
|
||||||
|
cy.get('.traversal-disabled .btn') |
||||||
|
.not('[disabled]').should('not.contain', 'Disabled') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.parent() - get parent DOM element from DOM elements', () => { |
||||||
|
// https://on.cypress.io/parent
|
||||||
|
cy.get('.traversal-mark') |
||||||
|
.parent().should('contain', 'Morbi leo risus') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.parents() - get parent DOM elements from DOM elements', () => { |
||||||
|
// https://on.cypress.io/parents
|
||||||
|
cy.get('.traversal-cite') |
||||||
|
.parents().should('match', 'blockquote') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.parentsUntil() - get parent DOM elements from DOM elements until el', () => { |
||||||
|
// https://on.cypress.io/parentsuntil
|
||||||
|
cy.get('.clothes-nav') |
||||||
|
.find('.active') |
||||||
|
.parentsUntil('.clothes-nav') |
||||||
|
.should('have.length', 2) |
||||||
|
}) |
||||||
|
|
||||||
|
it('.prev() - get previous sibling DOM element', () => { |
||||||
|
// https://on.cypress.io/prev
|
||||||
|
cy.get('.birds').find('.active') |
||||||
|
.prev().should('contain', 'Lorikeets') |
||||||
|
}) |
||||||
|
|
||||||
|
it('.prevAll() - get all previous sibling DOM elements', () => { |
||||||
|
// https://on.cypress.io/prevall
|
||||||
|
cy.get('.fruits-list').find('.third') |
||||||
|
.prevAll().should('have.length', 2) |
||||||
|
}) |
||||||
|
|
||||||
|
it('.prevUntil() - get all previous sibling DOM elements until el', () => { |
||||||
|
// https://on.cypress.io/prevuntil
|
||||||
|
cy.get('.foods-list').find('#nuts') |
||||||
|
.prevUntil('#veggies').should('have.length', 3) |
||||||
|
}) |
||||||
|
|
||||||
|
it('.siblings() - get all sibling DOM elements', () => { |
||||||
|
// https://on.cypress.io/siblings
|
||||||
|
cy.get('.traversal-pills .active') |
||||||
|
.siblings().should('have.length', 2) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,108 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Utilities', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/utilities') |
||||||
|
}) |
||||||
|
|
||||||
|
it('Cypress._ - call a lodash method', () => { |
||||||
|
// https://on.cypress.io/_
|
||||||
|
cy.request('https://jsonplaceholder.cypress.io/users') |
||||||
|
.then((response) => { |
||||||
|
let ids = Cypress._.chain(response.body).map('id').take(3).value() |
||||||
|
|
||||||
|
expect(ids).to.deep.eq([1, 2, 3]) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('Cypress.$ - call a jQuery method', () => { |
||||||
|
// https://on.cypress.io/$
|
||||||
|
let $li = Cypress.$('.utility-jquery li:first') |
||||||
|
|
||||||
|
cy.wrap($li) |
||||||
|
.should('not.have.class', 'active') |
||||||
|
.click() |
||||||
|
.should('have.class', 'active') |
||||||
|
}) |
||||||
|
|
||||||
|
it('Cypress.Blob - blob utilities and base64 string conversion', () => { |
||||||
|
// https://on.cypress.io/blob
|
||||||
|
cy.get('.utility-blob').then(($div) => { |
||||||
|
// https://github.com/nolanlawson/blob-util#imgSrcToDataURL
|
||||||
|
// get the dataUrl string for the javascript-logo
|
||||||
|
return Cypress.Blob.imgSrcToDataURL('https://example.cypress.io/assets/img/javascript-logo.png', undefined, 'anonymous') |
||||||
|
.then((dataUrl) => { |
||||||
|
// create an <img> element and set its src to the dataUrl
|
||||||
|
let img = Cypress.$('<img />', { src: dataUrl }) |
||||||
|
|
||||||
|
// need to explicitly return cy here since we are initially returning
|
||||||
|
// the Cypress.Blob.imgSrcToDataURL promise to our test
|
||||||
|
// append the image
|
||||||
|
$div.append(img) |
||||||
|
|
||||||
|
cy.get('.utility-blob img').click() |
||||||
|
.should('have.attr', 'src', dataUrl) |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it('Cypress.minimatch - test out glob patterns against strings', () => { |
||||||
|
// https://on.cypress.io/minimatch
|
||||||
|
let matching = Cypress.minimatch('/users/1/comments', '/users/*/comments', { |
||||||
|
matchBase: true, |
||||||
|
}) |
||||||
|
|
||||||
|
expect(matching, 'matching wildcard').to.be.true |
||||||
|
|
||||||
|
matching = Cypress.minimatch('/users/1/comments/2', '/users/*/comments', { |
||||||
|
matchBase: true, |
||||||
|
}) |
||||||
|
|
||||||
|
expect(matching, 'comments').to.be.false |
||||||
|
|
||||||
|
// ** matches against all downstream path segments
|
||||||
|
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/**', { |
||||||
|
matchBase: true, |
||||||
|
}) |
||||||
|
|
||||||
|
expect(matching, 'comments').to.be.true |
||||||
|
|
||||||
|
// whereas * matches only the next path segment
|
||||||
|
|
||||||
|
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/*', { |
||||||
|
matchBase: false, |
||||||
|
}) |
||||||
|
|
||||||
|
expect(matching, 'comments').to.be.false |
||||||
|
}) |
||||||
|
|
||||||
|
it('Cypress.Promise - instantiate a bluebird promise', () => { |
||||||
|
// https://on.cypress.io/promise
|
||||||
|
let waited = false |
||||||
|
|
||||||
|
/** |
||||||
|
* @return Bluebird<string> |
||||||
|
*/ |
||||||
|
function waitOneSecond () { |
||||||
|
// return a promise that resolves after 1 second
|
||||||
|
return new Cypress.Promise((resolve, reject) => { |
||||||
|
setTimeout(() => { |
||||||
|
// set waited to true
|
||||||
|
waited = true |
||||||
|
|
||||||
|
// resolve with 'foo' string
|
||||||
|
resolve('foo') |
||||||
|
}, 1000) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
cy.then(() => { |
||||||
|
// return a promise to cy.then() that
|
||||||
|
// is awaited until it resolves
|
||||||
|
return waitOneSecond().then((str) => { |
||||||
|
expect(str).to.eq('foo') |
||||||
|
expect(waited).to.be.true |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,59 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Viewport', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/commands/viewport') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.viewport() - set the viewport size and dimension', () => { |
||||||
|
// https://on.cypress.io/viewport
|
||||||
|
|
||||||
|
cy.get('#navbar').should('be.visible') |
||||||
|
cy.viewport(320, 480) |
||||||
|
|
||||||
|
// the navbar should have collapse since our screen is smaller
|
||||||
|
cy.get('#navbar').should('not.be.visible') |
||||||
|
cy.get('.navbar-toggle').should('be.visible').click() |
||||||
|
cy.get('.nav').find('a').should('be.visible') |
||||||
|
|
||||||
|
// lets see what our app looks like on a super large screen
|
||||||
|
cy.viewport(2999, 2999) |
||||||
|
|
||||||
|
// cy.viewport() accepts a set of preset sizes
|
||||||
|
// to easily set the screen to a device's width and height
|
||||||
|
|
||||||
|
// We added a cy.wait() between each viewport change so you can see
|
||||||
|
// the change otherwise it is a little too fast to see :)
|
||||||
|
|
||||||
|
cy.viewport('macbook-15') |
||||||
|
cy.wait(200) |
||||||
|
cy.viewport('macbook-13') |
||||||
|
cy.wait(200) |
||||||
|
cy.viewport('macbook-11') |
||||||
|
cy.wait(200) |
||||||
|
cy.viewport('ipad-2') |
||||||
|
cy.wait(200) |
||||||
|
cy.viewport('ipad-mini') |
||||||
|
cy.wait(200) |
||||||
|
cy.viewport('iphone-6+') |
||||||
|
cy.wait(200) |
||||||
|
cy.viewport('iphone-6') |
||||||
|
cy.wait(200) |
||||||
|
cy.viewport('iphone-5') |
||||||
|
cy.wait(200) |
||||||
|
cy.viewport('iphone-4') |
||||||
|
cy.wait(200) |
||||||
|
cy.viewport('iphone-3') |
||||||
|
cy.wait(200) |
||||||
|
|
||||||
|
// cy.viewport() accepts an orientation for all presets
|
||||||
|
// the default orientation is 'portrait'
|
||||||
|
cy.viewport('ipad-2', 'portrait') |
||||||
|
cy.wait(200) |
||||||
|
cy.viewport('iphone-4', 'landscape') |
||||||
|
cy.wait(200) |
||||||
|
|
||||||
|
// The viewport will be reset back to the default dimensions
|
||||||
|
// in between tests (the default can be set in cypress.config.{js|ts})
|
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,31 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Waiting', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/commands/waiting') |
||||||
|
}) |
||||||
|
// BE CAREFUL of adding unnecessary wait times.
|
||||||
|
// https://on.cypress.io/best-practices#Unnecessary-Waiting
|
||||||
|
|
||||||
|
// https://on.cypress.io/wait
|
||||||
|
it('cy.wait() - wait for a specific amount of time', () => { |
||||||
|
cy.get('.wait-input1').type('Wait 1000ms after typing') |
||||||
|
cy.wait(1000) |
||||||
|
cy.get('.wait-input2').type('Wait 1000ms after typing') |
||||||
|
cy.wait(1000) |
||||||
|
cy.get('.wait-input3').type('Wait 1000ms after typing') |
||||||
|
cy.wait(1000) |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.wait() - wait for a specific route', () => { |
||||||
|
// Listen to GET to comments/1
|
||||||
|
cy.intercept('GET', '**/comments/*').as('getComment') |
||||||
|
|
||||||
|
// we have code that gets a comment when
|
||||||
|
// the button is clicked in scripts.js
|
||||||
|
cy.get('.network-btn').click() |
||||||
|
|
||||||
|
// wait for GET comments/1
|
||||||
|
cy.wait('@getComment').its('response.statusCode').should('be.oneOf', [200, 304]) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,22 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
context('Window', () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.visit('https://example.cypress.io/commands/window') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.window() - get the global window object', () => { |
||||||
|
// https://on.cypress.io/window
|
||||||
|
cy.window().should('have.property', 'top') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.document() - get the document object', () => { |
||||||
|
// https://on.cypress.io/document
|
||||||
|
cy.document().should('have.property', 'charset').and('eq', 'UTF-8') |
||||||
|
}) |
||||||
|
|
||||||
|
it('cy.title() - get the title', () => { |
||||||
|
// https://on.cypress.io/title
|
||||||
|
cy.title().should('include', 'Kitchen Sink') |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,36 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
describe('empty spec', () => { |
||||||
|
it('Heineken new traffic', () => { |
||||||
|
cy.viewport(1400, 700); |
||||||
|
cy.visit(''); |
||||||
|
cy.get('[name="Usuario"]').type('alfonso'); |
||||||
|
cy.get('[name="Contrasena"]').type('garcia'); |
||||||
|
cy.get('[type="submit"]').click(); |
||||||
|
cy.visit('/RptCorresponsalesTraficos?proc=1&modo=1'); |
||||||
|
cy.contains('Nuevo').click(); |
||||||
|
cy.get('select#CmbCliente').select('2206'); |
||||||
|
cy.get('select#CmbOpEntrada').select('1'); |
||||||
|
cy.get('select#CmbOpSalida').select('1'); |
||||||
|
cy.get('select#CmbIDCorresponsal').select('16'); |
||||||
|
cy.get('#BtnSave1').click(); |
||||||
|
cy.wait(2000); |
||||||
|
cy.get('#LinkFacturas123').click(); |
||||||
|
let total = 123456; |
||||||
|
const uuid = () => Cypress._.random(0, 1e6); |
||||||
|
const id = uuid(); |
||||||
|
const Factura = `F${id}`; |
||||||
|
const Pedido = `P${id}`; |
||||||
|
Cypress._.times(5, (k) => { |
||||||
|
total = total + 10; |
||||||
|
cy.get('#Factura').clear(); |
||||||
|
cy.get('#ValorFacturaDls').clear(); |
||||||
|
cy.get('#Pedido').clear(); |
||||||
|
cy.get('#Factura').type(Factura); |
||||||
|
cy.get('#ValorFacturaDls').type(total); |
||||||
|
cy.get('#Pedido').type(Pedido); |
||||||
|
cy.get('#IDProveedor').select('51'); |
||||||
|
cy.get('#BtnSave').click(); |
||||||
|
cy.wait(2000); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,43 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
describe('empty spec', () => { |
||||||
|
it('Heineken new traffic', () => { |
||||||
|
cy.viewport(1400, 700); |
||||||
|
cy.visit(''); |
||||||
|
cy.get('[name="Usuario"]').type('alfonso'); |
||||||
|
cy.get('[name="Contrasena"]').type('garcia'); |
||||||
|
cy.get('[type="submit"]').click(); |
||||||
|
cy.visit('/RptCorresponsalesTraficos?proc=1&modo=1'); |
||||||
|
cy.contains('Nuevo').click(); |
||||||
|
cy.get('select#CmbCliente').select('2206'); |
||||||
|
cy.get('select#CmbOpEntrada').select('1'); |
||||||
|
cy.get('select#CmbOpSalida').select('1'); |
||||||
|
cy.get('select#CmbIDCorresponsal').select('16'); |
||||||
|
cy.get('#BtnSave1').click(); |
||||||
|
cy.wait(2000); |
||||||
|
cy.get('#LinkFacturasTerceros').click(); |
||||||
|
Cypress._.times(5, (k) => { |
||||||
|
cy.get('#Factura').clear(); |
||||||
|
cy.get('#Factura').type('FA123456'); |
||||||
|
cy.get('select#CmbIDProveedor').select('1'); |
||||||
|
cy.get('#BtnSave').click(); |
||||||
|
cy.wait(1000); |
||||||
|
}); |
||||||
|
/* let total = 123456; |
||||||
|
const uuid = () => Cypress._.random(0, 1e6); |
||||||
|
const id = uuid(); |
||||||
|
const Factura = `F${id}`; |
||||||
|
const Pedido = `P${id}`; |
||||||
|
Cypress._.times(5, (k) => { |
||||||
|
total = total + 10; |
||||||
|
cy.get('#Factura').clear(); |
||||||
|
cy.get('#ValorFacturaDls').clear(); |
||||||
|
cy.get('#Pedido').clear(); |
||||||
|
cy.get('#Factura').type(Factura); |
||||||
|
cy.get('#ValorFacturaDls').type(total); |
||||||
|
cy.get('#Pedido').type(Pedido); |
||||||
|
cy.get('#IDProveedor').select('51'); |
||||||
|
cy.get('#BtnSave').click(); |
||||||
|
cy.wait(2000);
|
||||||
|
});*/ |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,60 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
describe("empty spec", () => { |
||||||
|
it("Heineken new traffic", () => { |
||||||
|
cy.viewport(1400, 700); |
||||||
|
cy.visit(""); |
||||||
|
cy.get('[name="Usuario"]').type("alfonso"); |
||||||
|
cy.get('[name="Contrasena"]').type("garcia"); |
||||||
|
cy.get('[type="submit"]').click(); |
||||||
|
cy.visit("/RptCorresponsalesTraficos?proc=1&modo=1"); |
||||||
|
cy.contains("Nuevo").click(); |
||||||
|
cy.get("select#CmbCliente").select("2206"); |
||||||
|
cy.get("select#CmbOpEntrada").select("1"); |
||||||
|
cy.get("select#CmbOpSalida").select("1"); |
||||||
|
cy.get("select#CmbIDCorresponsal").select("16"); |
||||||
|
cy.get("#BtnSave1").click(); |
||||||
|
cy.wait(2000); |
||||||
|
cy.get("#LinkFacturas123").click(); |
||||||
|
let total = 123456; |
||||||
|
Cypress._.times(1, (k) => { |
||||||
|
const uuid = () => Cypress._.random(0, 1e6); |
||||||
|
const id = uuid(); |
||||||
|
const Factura = `F${id}`; |
||||||
|
const Pedido = `P${id}`; |
||||||
|
total = total + 10; |
||||||
|
cy.get("#Factura").clear(); |
||||||
|
cy.get("#ValorFacturaDls").clear(); |
||||||
|
cy.get("#Pedido").clear(); |
||||||
|
cy.get("#Factura").type(Factura); |
||||||
|
cy.get("#ValorFacturaDls").type(total); |
||||||
|
cy.get("#Pedido").type(Pedido); |
||||||
|
cy.get("#IDProveedor").select("51"); |
||||||
|
cy.get("#BtnSave").click(); |
||||||
|
cy.wait(2000); |
||||||
|
}); |
||||||
|
cy.get("body").trigger("keydown", { keyCode: 27 }); |
||||||
|
cy.wait(1000); |
||||||
|
cy.contains("Informacion corresponsal").click(); |
||||||
|
const uuid = () => Cypress._.random(0, 1e6); |
||||||
|
const id = uuid(); |
||||||
|
cy.get("#CTrafico").type(`TRA${id}`); |
||||||
|
cy.get("#FechaEntrada").type("2022-11-17"); |
||||||
|
cy.get("#FechaRevalidacionGuia").type("2022-11-17"); |
||||||
|
cy.get("#CFechaPago").type("2022-11-17"); |
||||||
|
Cypress._.times(10, (k) => { |
||||||
|
cy.contains("Agregar").click(); |
||||||
|
cy.wait(1000); |
||||||
|
cy.get("#CmbFacturas").select(1); |
||||||
|
cy.get("#DescripcionMaterial").type( |
||||||
|
"Esta es la descripcion del material" |
||||||
|
); |
||||||
|
cy.get("#FraccionArancelaria").type("FA123456"); |
||||||
|
cy.get("#ValorAduana").type("124578"); |
||||||
|
cy.get("#CDTA").type("224466", { force: true }); |
||||||
|
cy.get("#CIGI").type("446688", { force: true }); |
||||||
|
cy.get("#CIEPS").type("668800", { force: true }); |
||||||
|
cy.get("#BtnSavePartida").click(); |
||||||
|
cy.get("body").trigger("keydown", { keyCode: 27 }); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,13 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
describe('empty spec', () => { |
||||||
|
it('log in ok', () => { |
||||||
|
cy.visit('') |
||||||
|
cy.get('[name="Usuario"]') |
||||||
|
.type('alfonso') |
||||||
|
cy.get('[name="Contrasena"]') |
||||||
|
.type('garcia') |
||||||
|
cy.get('[type="submit"]') |
||||||
|
.click() |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,5 @@ |
|||||||
|
{ |
||||||
|
"name": "Using fixtures to represent data", |
||||||
|
"email": "hello@cypress.io", |
||||||
|
"body": "Fixtures are a great way to mock data for responses to routes" |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
// ***********************************************
|
||||||
|
// This example commands.ts shows you how to
|
||||||
|
// create various custom commands and overwrite
|
||||||
|
// existing commands.
|
||||||
|
//
|
||||||
|
// For more comprehensive examples of custom
|
||||||
|
// commands please read more here:
|
||||||
|
// https://on.cypress.io/custom-commands
|
||||||
|
// ***********************************************
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a parent command --
|
||||||
|
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a child command --
|
||||||
|
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a dual command --
|
||||||
|
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This will overwrite an existing command --
|
||||||
|
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||||
|
//
|
||||||
|
// declare global {
|
||||||
|
// namespace Cypress {
|
||||||
|
// interface Chainable {
|
||||||
|
// login(email: string, password: string): Chainable<void>
|
||||||
|
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
|
||||||
|
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
|
||||||
|
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
@ -0,0 +1,21 @@ |
|||||||
|
// ***********************************************************
|
||||||
|
// This example support/e2e.ts is processed and
|
||||||
|
// loaded automatically before your test files.
|
||||||
|
//
|
||||||
|
// This is a great place to put global configuration and
|
||||||
|
// behavior that modifies Cypress.
|
||||||
|
//
|
||||||
|
// You can change the location of this file or turn off
|
||||||
|
// automatically serving support files with the
|
||||||
|
// 'supportFile' configuration option.
|
||||||
|
//
|
||||||
|
// You can read more here:
|
||||||
|
// https://on.cypress.io/configuration
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
// Import commands.js using ES2015 syntax:
|
||||||
|
import "./commands"; |
||||||
|
|
||||||
|
// Alternatively you can use CommonJS syntax:
|
||||||
|
// require('./commands')
|
||||||
|
require("cypress-plugin-tab"); |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,88 @@ |
|||||||
|
{ |
||||||
|
"name": "gemco", |
||||||
|
"version": "0.1.0", |
||||||
|
"homepage": ".", |
||||||
|
"private": true, |
||||||
|
"dependencies": { |
||||||
|
"@reduxjs/toolkit": "^1.8.0", |
||||||
|
"@testing-library/jest-dom": "^5.16.2", |
||||||
|
"@testing-library/react": "^12.1.3", |
||||||
|
"@testing-library/user-event": "^13.5.0", |
||||||
|
"@types/jest": "^27.4.1", |
||||||
|
"@types/node": "^16.11.26", |
||||||
|
"@types/react": "^17.0.39", |
||||||
|
"@types/react-dom": "^17.0.13", |
||||||
|
"@types/react-redux": "^7.1.23", |
||||||
|
"a-chart": "^1.1.4", |
||||||
|
"ag-grid-community": "^27.0.1", |
||||||
|
"ag-grid-react": "^27.0.1", |
||||||
|
"apexcharts": "^3.35.3", |
||||||
|
"axios": "^0.26.0", |
||||||
|
"bootstrap": "^5.1.3", |
||||||
|
"btoa": "^1.2.1", |
||||||
|
"custom-item-select": "^1.2.3", |
||||||
|
"file-saver": "^2.0.5", |
||||||
|
"formik": "^2.2.9", |
||||||
|
"jwt-decode": "^3.1.2", |
||||||
|
"moment": "^2.29.1", |
||||||
|
"qr-scanner": "^1.4.1", |
||||||
|
"react": "^17.0.2", |
||||||
|
"react-apexcharts": "^1.4.0", |
||||||
|
"react-bootstrap": "^2.2.0", |
||||||
|
"react-currency-format": "^1.1.0", |
||||||
|
"react-data-export": "^0.6.0", |
||||||
|
"react-data-table-component": "^7.5.2", |
||||||
|
"react-data-table-component-extensions": "^1.6.0", |
||||||
|
"react-datepicker": "^4.8.0", |
||||||
|
"react-datetime": "^3.1.1", |
||||||
|
"react-dom": "^17.0.2", |
||||||
|
"react-drag-drop-files": "^2.3.5", |
||||||
|
"react-dropdown-select": "^4.9.0", |
||||||
|
"react-dropzone": "^14.2.1", |
||||||
|
"react-flexy-table": "^1.8.10", |
||||||
|
"react-google-qrcode": "^1.0.3", |
||||||
|
"react-grid-data": "^1.1.5", |
||||||
|
"react-icons": "^4.3.1", |
||||||
|
"react-print-components": "^1.0.4", |
||||||
|
"react-redux": "^7.2.6", |
||||||
|
"react-router-dom": "6", |
||||||
|
"react-scripts": "5.0.0", |
||||||
|
"react-to-print": "^2.14.7", |
||||||
|
"react-webcam-qr-scanner.ts": "^1.0.4", |
||||||
|
"redux": "^4.1.2", |
||||||
|
"redux-starter-kit": "^2.0.0", |
||||||
|
"string-hex": "^1.0.0", |
||||||
|
"typescript": "^4.6.2", |
||||||
|
"web-vitals": "^2.1.4", |
||||||
|
"xlsx": "^0.18.4", |
||||||
|
"yup": "^0.32.11" |
||||||
|
}, |
||||||
|
"scripts": { |
||||||
|
"start": "react-scripts start", |
||||||
|
"build": "react-scripts build", |
||||||
|
"test": "react-scripts test", |
||||||
|
"eject": "react-scripts eject" |
||||||
|
}, |
||||||
|
"eslintConfig": { |
||||||
|
"extends": [ |
||||||
|
"react-app", |
||||||
|
"react-app/jest" |
||||||
|
] |
||||||
|
}, |
||||||
|
"browserslist": { |
||||||
|
"production": [ |
||||||
|
">0.2%", |
||||||
|
"not dead", |
||||||
|
"not op_mini all" |
||||||
|
], |
||||||
|
"development": [ |
||||||
|
"last 1 chrome version", |
||||||
|
"last 1 firefox version", |
||||||
|
"last 1 safari version" |
||||||
|
] |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"cypress": "^11.0.1", |
||||||
|
"cypress-plugin-tab": "^1.0.5" |
||||||
|
} |
||||||
|
} |
After Width: | Height: | Size: 227 KiB |
@ -0,0 +1,43 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8" /> |
||||||
|
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> |
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" /> |
||||||
|
<meta name="theme-color" content="#000000" /> |
||||||
|
<meta |
||||||
|
name="description" |
||||||
|
content="Web site created using create-react-app" |
||||||
|
/> |
||||||
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> |
||||||
|
<!-- |
||||||
|
manifest.json provides metadata used when your web app is installed on a |
||||||
|
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ |
||||||
|
--> |
||||||
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> |
||||||
|
<!-- |
||||||
|
Notice the use of %PUBLIC_URL% in the tags above. |
||||||
|
It will be replaced with the URL of the `public` folder during the build. |
||||||
|
Only files inside the `public` folder can be referenced from the HTML. |
||||||
|
|
||||||
|
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will |
||||||
|
work correctly both with client-side routing and a non-root public URL. |
||||||
|
Learn how to configure a non-root public URL by running `npm run build`. |
||||||
|
--> |
||||||
|
<title>GEMCO</title> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<noscript>You need to enable JavaScript to run this app.</noscript> |
||||||
|
<div id="root"></div> |
||||||
|
<!-- |
||||||
|
This HTML file is a template. |
||||||
|
If you open it directly in the browser, you will see an empty page. |
||||||
|
|
||||||
|
You can add webfonts, meta tags, or analytics to this file. |
||||||
|
The build step will place the bundled scripts into the <body> tag. |
||||||
|
|
||||||
|
To begin the development, run `npm start` or `yarn start`. |
||||||
|
To create a production bundle, use `npm run build` or `yarn build`. |
||||||
|
--> |
||||||
|
</body> |
||||||
|
</html> |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 9.4 KiB |
@ -0,0 +1,25 @@ |
|||||||
|
{ |
||||||
|
"short_name": "React App", |
||||||
|
"name": "Create React App Sample", |
||||||
|
"icons": [ |
||||||
|
{ |
||||||
|
"src": "GEMCO.ico", |
||||||
|
"sizes": "64x64 32x32 24x24 16x16", |
||||||
|
"type": "image/x-icon" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"src": "logo192.png", |
||||||
|
"type": "image/png", |
||||||
|
"sizes": "192x192" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"src": "logo512.png", |
||||||
|
"type": "image/png", |
||||||
|
"sizes": "512x512" |
||||||
|
} |
||||||
|
], |
||||||
|
"start_url": ".", |
||||||
|
"display": "standalone", |
||||||
|
"theme_color": "#000000", |
||||||
|
"background_color": "#ffffff" |
||||||
|
} |
@ -0,0 +1,3 @@ |
|||||||
|
# https://www.robotstxt.org/robotstxt.html |
||||||
|
User-agent: * |
||||||
|
Disallow: |
@ -0,0 +1,7 @@ |
|||||||
|
{ |
||||||
|
"trailingComma": "none", |
||||||
|
"tabWidth": 2, |
||||||
|
"semi": false, |
||||||
|
"singleQuote": true, |
||||||
|
"max_line_length": 120 |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
.App { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
.App-logo { |
||||||
|
height: 40vmin; |
||||||
|
pointer-events: none; |
||||||
|
} |
||||||
|
|
||||||
|
@media (prefers-reduced-motion: no-preference) { |
||||||
|
.App-logo { |
||||||
|
animation: App-logo-spin infinite 20s linear; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.App-header { |
||||||
|
background-color: #282c34; |
||||||
|
min-height: 100vh; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
font-size: calc(10px + 2vmin); |
||||||
|
color: white; |
||||||
|
} |
||||||
|
|
||||||
|
.App-link { |
||||||
|
color: #61dafb; |
||||||
|
} |
||||||
|
|
||||||
|
@keyframes App-logo-spin { |
||||||
|
from { |
||||||
|
transform: rotate(0deg); |
||||||
|
} |
||||||
|
to { |
||||||
|
transform: rotate(360deg); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,120 @@ |
|||||||
|
import React, { useEffect, useState } from 'react' |
||||||
|
import { Outlet, useNavigate } from 'react-router-dom' |
||||||
|
import { Container, Form, Nav, Navbar, NavDropdown } from 'react-bootstrap' |
||||||
|
import ItemMenu from './Interfaces/Catalogos/IItemMenu' |
||||||
|
import 'ag-grid-community/dist/styles/ag-grid.css' |
||||||
|
import 'ag-grid-community/dist/styles/ag-theme-alpine.css' |
||||||
|
import usuariosServices from './Services/Catalogos/Usuarios.Services' |
||||||
|
import { logued } from './store/features/userStatusSlice/userStatusSlice' |
||||||
|
import { useSelector, useDispatch } from 'react-redux' |
||||||
|
import { RootState } from './store/store' |
||||||
|
import { MsgInformativo } from './Components/Utils/Toast/msgInformativo' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import { BsPersonCircle } from 'react-icons/bs' |
||||||
|
import Submenu from './Components/Submenu/Submenu' |
||||||
|
|
||||||
|
function App() { |
||||||
|
const navigate = useNavigate() |
||||||
|
const dispatch = useDispatch() |
||||||
|
let _menu: ItemMenu[] = [] |
||||||
|
const [mainMenu, setMainMenu] = useState(_menu) |
||||||
|
const userLogued = useSelector((state: RootState) => state.userStatus.value) |
||||||
|
const [show, setShow] = useState(false) |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const msgColor = 'primary' |
||||||
|
const menu = localStorage.getItem('menu') ? localStorage.getItem('menu') : '' |
||||||
|
const User = () => { |
||||||
|
const stickyValue = window.localStorage.getItem('User') |
||||||
|
return stickyValue !== null ? JSON.parse(stickyValue) : '' |
||||||
|
} |
||||||
|
const [Depto, setDepto] = useState(() => { |
||||||
|
const stickyValue = window.localStorage.getItem('Departamento') |
||||||
|
return stickyValue !== null |
||||||
|
? JSON.parse(stickyValue).substring(0, 4) + '.' |
||||||
|
: '' |
||||||
|
}) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (menu && userLogued) { |
||||||
|
setMainMenu(JSON.parse(menu)) |
||||||
|
} else { |
||||||
|
setMainMenu([]) |
||||||
|
} |
||||||
|
}, [menu, userLogued]) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
usuariosServices |
||||||
|
.validate() |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
dispatch(logued(true)) |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
if (!window.location.href.indexOf('login')) { |
||||||
|
localStorage.setItem('menu', '') |
||||||
|
localStorage.setItem('token', '') |
||||||
|
setHeader('Informativo') |
||||||
|
setMsg('Su session ha expirado, necesita volver a loguerse') |
||||||
|
setShow(true) |
||||||
|
navigate('/') |
||||||
|
} |
||||||
|
}) |
||||||
|
}, [dispatch, navigate]) |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="App"> |
||||||
|
<Navbar className="custom-theme" bg="light" expand="lg"> |
||||||
|
<Container> |
||||||
|
<Navbar.Brand href="/" style={{ color: '#FFFFFF' }}> |
||||||
|
GEMCO |
||||||
|
</Navbar.Brand> |
||||||
|
<Navbar.Toggle aria-controls="basic-navbar-nav" /> |
||||||
|
<Navbar.Collapse id="basic-navbar-nav"> |
||||||
|
<Nav className="me-auto"> |
||||||
|
{mainMenu |
||||||
|
? mainMenu.map((itemMenu, index) => { |
||||||
|
if (itemMenu.padreId === 0) { |
||||||
|
return ( |
||||||
|
<> |
||||||
|
<Submenu |
||||||
|
descripcion={itemMenu.descripcion} |
||||||
|
key={itemMenu.id} |
||||||
|
allItems={mainMenu} |
||||||
|
submenu={mainMenu.filter(function (item) { |
||||||
|
return item.padreId === itemMenu.id |
||||||
|
})} |
||||||
|
/> |
||||||
|
</> |
||||||
|
) |
||||||
|
} |
||||||
|
}) |
||||||
|
: ''} |
||||||
|
</Nav> |
||||||
|
<Form className="d-flex"> |
||||||
|
{!userLogued ? ( |
||||||
|
<> |
||||||
|
<Nav.Link href="/#/login">Login</Nav.Link> |
||||||
|
<Nav.Link href="/#/reset">Reset</Nav.Link> |
||||||
|
</> |
||||||
|
) : ( |
||||||
|
<> |
||||||
|
<Nav.Link href="/#/logout">Logout</Nav.Link> |
||||||
|
<div style={{ paddingTop: '5px' }}>{User} </div> |
||||||
|
<IconContext.Provider value={{ size: '25px' }}> |
||||||
|
<BsPersonCircle /> |
||||||
|
</IconContext.Provider> |
||||||
|
<div style={{ paddingTop: '5px' }}>{Depto} </div> |
||||||
|
</> |
||||||
|
)} |
||||||
|
</Form> |
||||||
|
</Navbar.Collapse> |
||||||
|
</Container> |
||||||
|
</Navbar> |
||||||
|
<Outlet /> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default App |
@ -0,0 +1,181 @@ |
|||||||
|
import ICorresponsalTrafico from "../../Interfaces/Corresponsales/ICorresponsalTrafico"; |
||||||
|
|
||||||
|
export default class CCorresponsalesTrafico implements ICorresponsalTrafico { |
||||||
|
id: number=0 |
||||||
|
folioGemco: string
|
||||||
|
fechaRegistro?: string
|
||||||
|
idUsuario: number=0
|
||||||
|
idCliente: number=0
|
||||||
|
tipoOperacion: number=0 |
||||||
|
opEntrada: number=0
|
||||||
|
opSalida: number=0
|
||||||
|
idCorresponsal: number=0
|
||||||
|
bultos?: number
|
||||||
|
kilos?: number
|
||||||
|
estatus?: number
|
||||||
|
trafico?: string
|
||||||
|
aduana?: number
|
||||||
|
patente?: number
|
||||||
|
pedimento?: number
|
||||||
|
clave?: string
|
||||||
|
fechaPago?: string
|
||||||
|
tipoCambio?: number
|
||||||
|
valorAduanaMN?: number
|
||||||
|
totalPagado?: number
|
||||||
|
valorFacturaMN?: number
|
||||||
|
cantidadFracciones?: number
|
||||||
|
buque?: string
|
||||||
|
valorFacturaDls?: number
|
||||||
|
descripcionMercancia?: string
|
||||||
|
observaciones?: string
|
||||||
|
fechaDesaduanamiento: string |
||||||
|
semaforoFiscal?: number
|
||||||
|
noCuenta?: string
|
||||||
|
fechaCuenta?: string
|
||||||
|
tipoMercancia?: number
|
||||||
|
ultimaActualizacion?: string |
||||||
|
zipgemco?: string;
|
||||||
|
zipCorresponsales?: string; |
||||||
|
proceso: number; |
||||||
|
rechazado: number; |
||||||
|
idTabulador: number; |
||||||
|
noRecti: number; |
||||||
|
estatusCode: number; |
||||||
|
activo?: number
|
||||||
|
|
||||||
|
constructor() { |
||||||
|
this.id=0
|
||||||
|
this.folioGemco='' |
||||||
|
this.fechaRegistro='' |
||||||
|
this.idUsuario=0
|
||||||
|
this.idCliente=0
|
||||||
|
this.tipoOperacion=0 |
||||||
|
this.opEntrada=0
|
||||||
|
this.opSalida=0
|
||||||
|
this.idCorresponsal=0
|
||||||
|
this.bultos=0
|
||||||
|
this.kilos=0
|
||||||
|
this.estatus=0
|
||||||
|
this.trafico=''
|
||||||
|
this.aduana=0
|
||||||
|
this.patente=0
|
||||||
|
this.pedimento=0
|
||||||
|
this.clave=''
|
||||||
|
this.fechaPago=''
|
||||||
|
this.tipoCambio=0
|
||||||
|
this.valorAduanaMN=0 |
||||||
|
this.totalPagado=0
|
||||||
|
this.valorFacturaMN=0
|
||||||
|
this.cantidadFracciones=0
|
||||||
|
this.buque='' |
||||||
|
this.valorFacturaDls=0
|
||||||
|
this.descripcionMercancia=''
|
||||||
|
this.observaciones=''
|
||||||
|
this.fechaDesaduanamiento='' |
||||||
|
this.semaforoFiscal=0
|
||||||
|
this.noCuenta=''
|
||||||
|
this.fechaCuenta=''
|
||||||
|
this.tipoMercancia=0
|
||||||
|
this.ultimaActualizacion='' |
||||||
|
this.zipgemco=''
|
||||||
|
this.zipCorresponsales='' |
||||||
|
this.proceso=1 |
||||||
|
this.rechazado=1 |
||||||
|
this.idTabulador=0 |
||||||
|
this.noRecti=0; |
||||||
|
this.estatusCode=0; |
||||||
|
this.activo=1
|
||||||
|
} |
||||||
|
|
||||||
|
public getEmptyObject(): ICorresponsalTrafico { |
||||||
|
return { |
||||||
|
id: 0,
|
||||||
|
folioGemco:'', |
||||||
|
fechaRegistro: '', |
||||||
|
idUsuario :0,
|
||||||
|
idCliente :0,
|
||||||
|
tipoOperacion :0, |
||||||
|
opEntrada :0,
|
||||||
|
opSalida:0, |
||||||
|
idCorresponsal :0,
|
||||||
|
bultos :0,
|
||||||
|
kilos :0,
|
||||||
|
estatus :0,
|
||||||
|
trafico :'',
|
||||||
|
aduana :0,
|
||||||
|
patente :0,
|
||||||
|
pedimento :0,
|
||||||
|
clave :'',
|
||||||
|
fechaPago :'',
|
||||||
|
tipoCambio :0,
|
||||||
|
valorAduanaMN :0, |
||||||
|
totalPagado :0,
|
||||||
|
valorFacturaMN :0,
|
||||||
|
cantidadFracciones :0,
|
||||||
|
buque :'', |
||||||
|
valorFacturaDls :0,
|
||||||
|
descripcionMercancia :'',
|
||||||
|
observaciones :'',
|
||||||
|
fechaDesaduanamiento :'', |
||||||
|
semaforoFiscal :0,
|
||||||
|
noCuenta :'',
|
||||||
|
fechaCuenta :'',
|
||||||
|
tipoMercancia :0,
|
||||||
|
ultimaActualizacion :'',
|
||||||
|
zipgemco:'',
|
||||||
|
zipCorresponsales:'', |
||||||
|
proceso:1, |
||||||
|
rechazado:1, |
||||||
|
idTabulador:0, |
||||||
|
noRecti:0, |
||||||
|
estatusCode:0, |
||||||
|
activo :1
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public setObject(data: ICorresponsalTrafico): ICorresponsalTrafico { |
||||||
|
return { |
||||||
|
id: data.id,
|
||||||
|
folioGemco: data.folioGemco, |
||||||
|
fechaRegistro: data.fechaRegistro, |
||||||
|
idUsuario : data.idUsuario,
|
||||||
|
idCliente :data.idCliente,
|
||||||
|
tipoOperacion :data.tipoOperacion, |
||||||
|
opEntrada : data.opEntrada,
|
||||||
|
opSalida: data.opSalida, |
||||||
|
idCorresponsal : data.idCorresponsal,
|
||||||
|
bultos :data.bultos,
|
||||||
|
kilos : data.kilos,
|
||||||
|
estatus : data.estatus,
|
||||||
|
trafico : data.trafico,
|
||||||
|
aduana : data.aduana,
|
||||||
|
patente : data.patente,
|
||||||
|
pedimento : data.pedimento,
|
||||||
|
clave : data.clave,
|
||||||
|
fechaPago : data.fechaPago,
|
||||||
|
tipoCambio : data.tipoCambio,
|
||||||
|
valorAduanaMN : data.valorAduanaMN, |
||||||
|
totalPagado : data.totalPagado,
|
||||||
|
valorFacturaMN : data.valorFacturaMN,
|
||||||
|
cantidadFracciones : data.cantidadFracciones,
|
||||||
|
buque : data.buque, |
||||||
|
valorFacturaDls : data.valorFacturaDls,
|
||||||
|
descripcionMercancia : data.descripcionMercancia,
|
||||||
|
observaciones : data.observaciones,
|
||||||
|
fechaDesaduanamiento : data.fechaDesaduanamiento, |
||||||
|
semaforoFiscal : data.semaforoFiscal,
|
||||||
|
noCuenta : data.noCuenta,
|
||||||
|
fechaCuenta : data.fechaCuenta,
|
||||||
|
tipoMercancia : data.tipoMercancia,
|
||||||
|
ultimaActualizacion : data.ultimaActualizacion,
|
||||||
|
zipgemco: data.zipgemco, |
||||||
|
zipCorresponsales: data.zipCorresponsales, |
||||||
|
proceso: data.proceso, |
||||||
|
rechazado: data.rechazado, |
||||||
|
idTabulador: data.idTabulador, |
||||||
|
noRecti: data.noRecti, |
||||||
|
estatusCode: data.estatusCode, |
||||||
|
activo : data.activo
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,276 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import { Alert, Card, Col, Row } from 'react-bootstrap' |
||||||
|
import QRCode from 'react-google-qrcode' |
||||||
|
import Header from '../../../images/AvisoCruceHeader.png' |
||||||
|
import Footer from '../../../images/AvisoCruceFooter.png' |
||||||
|
import PrintComponents from 'react-print-components' |
||||||
|
|
||||||
|
interface IProps {} |
||||||
|
|
||||||
|
export const AvisoCruce: FC<IProps> = (props) => { |
||||||
|
const [AvisoCruce, setAvisoCruce] = useState('') |
||||||
|
const [Validacion, setValidacion] = useState('') |
||||||
|
const [Aduana, setAduana] = useState('') |
||||||
|
const [Emision, setEmision] = useState('') |
||||||
|
const [TipoOperacion, setTipoOperacion] = useState('') |
||||||
|
const [TipoDocumento, setTipoDocumento] = useState('') |
||||||
|
const [InformacionTipoDocumento, setInformacionTipoDocumento] = useState('') |
||||||
|
const [ModalidadCruce, setModalidadCruce] = useState('') |
||||||
|
const [FechaEmision, setFechaEmision] = useState('') |
||||||
|
const [Contenedor, setContenedor] = useState('') |
||||||
|
const [Candado, setCandado] = useState('') |
||||||
|
const [URL, setURL] = useState<string>() |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
setURL('https://sea-avc.anam.gob.mx/show/show/' + AvisoCruce) |
||||||
|
}, [AvisoCruce]) |
||||||
|
|
||||||
|
function QRCodeBuilder(url: string) { |
||||||
|
return <QRCode data={url} size={130} frame /> |
||||||
|
} |
||||||
|
|
||||||
|
const showFile1 = (e: any) => { |
||||||
|
e.preventDefault() |
||||||
|
setAvisoCruce('') |
||||||
|
setAduana('') |
||||||
|
setEmision('') |
||||||
|
setTipoOperacion('') |
||||||
|
setTipoDocumento('') |
||||||
|
setInformacionTipoDocumento('') |
||||||
|
setModalidadCruce('') |
||||||
|
setFechaEmision('') |
||||||
|
setContenedor('') |
||||||
|
setCandado('') |
||||||
|
setURL('') |
||||||
|
const reader = new FileReader() |
||||||
|
reader.onload = async (e: any) => { |
||||||
|
const text = e.target.result |
||||||
|
const arr: string[] = text.split(/\r?\n/) |
||||||
|
console.log(arr) |
||||||
|
let Contenedores = '', |
||||||
|
Candados = '' |
||||||
|
for (var i = 0; i < arr.length; i++) { |
||||||
|
// console.log(arr[i])
|
||||||
|
if (arr[i].includes('Aviso de cruce:')) { |
||||||
|
setAvisoCruce(arr[i].replace('Aviso de cruce:', '')) |
||||||
|
} |
||||||
|
if (arr[i].includes('Emisión:')) setEmision(arr[i].replace('Emisión:', '')) |
||||||
|
if (arr[i].includes('Aduana')) setAduana(arr[i].replace('Aduana:', '')) |
||||||
|
if (arr[i].includes('Tipo de operación:')) setTipoOperacion(arr[i].replace('Tipo de operación:', '')) |
||||||
|
if (arr[i].includes('Tipo de documento:')) setTipoDocumento(arr[i].replace('Tipo de documento:', '')) |
||||||
|
if (arr[i].includes('|')) setInformacionTipoDocumento(arr[i]) |
||||||
|
if (arr[i].includes('Modalidad')) setModalidadCruce(arr[i]) |
||||||
|
if (arr[i].includes('Fecha de Emisi')) setFechaEmision(arr[i]) |
||||||
|
if (arr[i].includes('Contenedor-caja:')) { |
||||||
|
Contenedores = '' |
||||||
|
for (var ii = i; ii < arr.length; ii++) { |
||||||
|
console.log('valor de caja contenedor ' + arr[ii]) |
||||||
|
if (arr[ii].length > 0) { |
||||||
|
Contenedores += ',' + arr[ii] |
||||||
|
console.log('Contenedores ' + Contenedores) |
||||||
|
} else { |
||||||
|
i = ii |
||||||
|
Contenedores = Contenedores.replace(',Contenedor-caja:,', '') |
||||||
|
setContenedor(Contenedores) |
||||||
|
console.log('........................................Caja Contenedor value:' + Contenedores) |
||||||
|
break |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (arr[i].includes('Candados:')) { |
||||||
|
Candados = '' |
||||||
|
for (var ii = i; ii < arr.length; ii++) { |
||||||
|
console.log('valor de candados ' + arr[ii]) |
||||||
|
if (arr[ii].length > 0) { |
||||||
|
Candados += ',' + arr[ii] |
||||||
|
console.log('Candados ' + Candado) |
||||||
|
} else { |
||||||
|
i = ii |
||||||
|
Candados = Candados.replace(',Candados:,', '') |
||||||
|
setCandado(Candados) |
||||||
|
console.log('........................................Candado value:' + Candados) |
||||||
|
break |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
reader.readAsText(e.target.files[0]) |
||||||
|
} |
||||||
|
|
||||||
|
const showFile2 = (e: any) => { |
||||||
|
e.preventDefault() |
||||||
|
const reader = new FileReader() |
||||||
|
reader.onload = async (e: any) => { |
||||||
|
const text = e.target.result |
||||||
|
console.log(text) |
||||||
|
setValidacion(text.replace('"', '')) |
||||||
|
} |
||||||
|
reader.readAsText(e.target.files[0]) |
||||||
|
} |
||||||
|
|
||||||
|
const generatePDF = () => {} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className='allScreen'> |
||||||
|
{AvisoCruce === '' || Validacion === '' ? ( |
||||||
|
<div> |
||||||
|
<Row> |
||||||
|
<Col xs={12}> </Col> |
||||||
|
</Row> |
||||||
|
<Card> |
||||||
|
<Card.Body> |
||||||
|
<Row> |
||||||
|
<Col> |
||||||
|
<Alert variant='secondary'></Alert> |
||||||
|
Proporcione el archivo AVC |
||||||
|
</Col> |
||||||
|
<Col> |
||||||
|
<Alert variant='secondary'> |
||||||
|
<input type='file' onChange={(e) => showFile1(e)} /> |
||||||
|
</Alert> |
||||||
|
</Col> |
||||||
|
<Col xs={3}></Col> |
||||||
|
<Col>Proporcione el archivo de validacion</Col> |
||||||
|
<Col> |
||||||
|
<input type='file' onChange={(e) => showFile2(e)} /> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Card.Body> |
||||||
|
</Card> |
||||||
|
</div> |
||||||
|
) : ( |
||||||
|
<div> |
||||||
|
<Row> |
||||||
|
<Col xs={12}> </Col> |
||||||
|
</Row> |
||||||
|
{/* <Row> |
||||||
|
<Col xs={8}> |
||||||
|
<Card style={{ textAlign: 'center', width: '1000px', height: '100%' }}> |
||||||
|
<Card.Img variant='top' src={Header} /> |
||||||
|
</Card> |
||||||
|
</Col> |
||||||
|
<Col xs={4}></Col> |
||||||
|
</Row> */} |
||||||
|
<Row> |
||||||
|
<Col xs={12}> </Col> |
||||||
|
</Row> |
||||||
|
<Row> |
||||||
|
<Col xs={8}> |
||||||
|
<PrintComponents trigger={<button>Print</button>}> |
||||||
|
<table className='tableAvisoCruce allScreen'> |
||||||
|
<tr> |
||||||
|
<th colSpan={4} style={{ textAlign: 'center' }} className='tableAvisoCruceHeader'> |
||||||
|
AVISO DE CRUCE |
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
<tr className='tableAvisoCruceHeader'> |
||||||
|
<th colSpan={3}>FOLIO AVISO DE CRUCE</th> |
||||||
|
<td>FECHA DE EMISIÓN</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<th colSpan={3} className='tableAvisoCrucefNormal'> |
||||||
|
{AvisoCruce} |
||||||
|
</th> |
||||||
|
<td>{Emision}</td> |
||||||
|
</tr> |
||||||
|
<tr className='tableAvisoCruceHeader'> |
||||||
|
<td colSpan={2}>ADUANA</td> |
||||||
|
<td>TIPO OPERACIÓN</td> |
||||||
|
<td>TIPO DE DOCUMENTO</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td colSpan={2} rowSpan={3}> |
||||||
|
{Aduana} |
||||||
|
</td> |
||||||
|
<td>{TipoOperacion}</td> |
||||||
|
<td>{TipoDocumento}</td> |
||||||
|
</tr> |
||||||
|
<tr className='tableAvisoCruceHeader'> |
||||||
|
<td>MODALIDAD DE CRUCE</td> |
||||||
|
<td>TAG-GAFETE ÚNICO</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td>VEHICULAR</td> |
||||||
|
<td></td> |
||||||
|
</tr> |
||||||
|
<tr className='tableAvisoCruceHeader'> |
||||||
|
<th colSpan={3}>CONTENEDOR-CAJA</th> |
||||||
|
<td>CANDADOS</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<th colSpan={3} className='tableAvisoCrucefNormal'> |
||||||
|
{Contenedor} |
||||||
|
</th> |
||||||
|
<td>{Candado}</td> |
||||||
|
</tr> |
||||||
|
<tr className='tableAvisoCruceHeader'> |
||||||
|
<th colSpan={4}>INFORMACIÓN DEL TIPO DE DOCUMENTO</th> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<th colSpan={4} className='tableAvisoCrucefNormal'> |
||||||
|
{InformacionTipoDocumento} |
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
<tr className='tableAvisoCruceHeader'> |
||||||
|
<th colSpan={4}>FOLIO FISCAL DEL CFDI CON COMPLEMENTO CARTA PORTE</th> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<th colSpan={4} className='tableAvisoCrucefNormal'> |
||||||
|
|
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
<tr className='tableAvisoCruceHeader'> |
||||||
|
<th colSpan={3}>DATOS ADICIONALES</th> |
||||||
|
<th colSpan={1}>CÓDIGO BIDIMENCIONAL QR</th> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<th colSpan={3} className='tableAvisoCrucefNormal'> |
||||||
|
|
||||||
|
</th> |
||||||
|
<th colSpan={1}> |
||||||
|
<Row> |
||||||
|
<Col xs={3}> </Col> |
||||||
|
<Col xs={6}> |
||||||
|
<br /> |
||||||
|
<img src={'https://chart.googleapis.com/chart?cht=qr&chl=' + URL + '&chs=200x200'} /> |
||||||
|
<br /> |
||||||
|
</Col> |
||||||
|
<Col xs={3}></Col> |
||||||
|
</Row> |
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
<tr className='tableAvisoCruceHeader'> |
||||||
|
<th colSpan={4}>FOLIÓ DE VALICACIÓN DE LA AGENCIA</th> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<th colSpan={4} className='tableAvisoCrucefNormal tdAvisoCruceWordWrap'> |
||||||
|
{Validacion} |
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<th colSpan={4}> |
||||||
|
<img src={Footer} /> |
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
</PrintComponents> |
||||||
|
</Col> |
||||||
|
<Col xs={4}></Col> |
||||||
|
</Row> |
||||||
|
{/* <Row> |
||||||
|
<Col xs={12}> </Col> |
||||||
|
</Row> |
||||||
|
<Row> |
||||||
|
<Col xs={8}> |
||||||
|
<Card style={{ textAlign: 'center', width: '1000px', height: '100%' }}> |
||||||
|
<Card.Img variant='top' src={Footer} /> |
||||||
|
</Card> |
||||||
|
</Col> |
||||||
|
<Col xs={4}></Col> |
||||||
|
</Row> */} |
||||||
|
</div> |
||||||
|
)} |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,149 @@ |
|||||||
|
import { FC, useState } from 'react' |
||||||
|
// Bootstrap components
|
||||||
|
import { Button, Card, Col, Container, Form, Modal, Row } from 'react-bootstrap' |
||||||
|
// Interfaces
|
||||||
|
import IFotosBodega from '../../Interfaces/IFotosBodega' |
||||||
|
//Services
|
||||||
|
import archivoElectronicoServices from '../../Services/Catalogos/ArchivoElectronico.Services' |
||||||
|
// GUI components
|
||||||
|
import '../../css/imageModal.css' |
||||||
|
import { MsgInformativo } from '../Utils/Toast/msgInformativo' |
||||||
|
import { TargetURL } from '../../Constants/TargetURL' |
||||||
|
const URL = new TargetURL() |
||||||
|
|
||||||
|
interface IProps {} |
||||||
|
export const FotosBodega: FC<IProps> = (props) => { |
||||||
|
const [API, setAPI] = useState(URL.get() + '/ArchivoElectronico/getPictureContent?Nombre=') |
||||||
|
const [Referencia, setReferencia] = useState('') |
||||||
|
const [imageFullSize, setImageFullSize] = useState('') |
||||||
|
const [show, setShow] = useState(false) |
||||||
|
const [FileList, setFileList] = useState<Array<IFotosBodega>>([]) |
||||||
|
const [MsgShow, setMsgShow] = useState(false) |
||||||
|
const [MsgTxt, setMsgTxt] = useState('') |
||||||
|
const [MsgAlerta, setMsgAlerta] = useState('Alerta') |
||||||
|
const [MsgColor, setMsgColor] = useState('primary') |
||||||
|
|
||||||
|
function getPictureInfo() { |
||||||
|
if (Referencia.length === 0) { |
||||||
|
setMsgTxt('Proporcione la referencia por favor...') |
||||||
|
setMsgShow(true) |
||||||
|
return false |
||||||
|
} |
||||||
|
const data: IFotosBodega = { |
||||||
|
id: 0, |
||||||
|
nombre: null, |
||||||
|
referencia: Referencia, |
||||||
|
registrado: null, |
||||||
|
proceso: null, |
||||||
|
creado: null, |
||||||
|
usuario: null, |
||||||
|
comentarios: null, |
||||||
|
activo: 1, |
||||||
|
} |
||||||
|
archivoElectronicoServices |
||||||
|
.getInfoPicturesFromWarehouse(data) |
||||||
|
.then((response) => { |
||||||
|
setFileList(response.data) |
||||||
|
console.log(response.data) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
console.log(e) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
function showFullSize(picture: any) { |
||||||
|
setImageFullSize(picture) |
||||||
|
setShow(true) |
||||||
|
} |
||||||
|
|
||||||
|
function getProcessName(proc: any): string { |
||||||
|
let tipoProceso = '' |
||||||
|
if (proc == 1) tipoProceso = 'CAJA LLEGO' |
||||||
|
if (proc == 2) tipoProceso = 'RECIBO ASI LLEGO' |
||||||
|
if (proc == 3) tipoProceso = 'REVISION' |
||||||
|
if (proc == 4) tipoProceso = 'ASI SE FUE' |
||||||
|
if (proc == 5) tipoProceso = 'DAÑOS SIN GEMCO' |
||||||
|
if (proc == 6) tipoProceso = 'ETIQUETADO' |
||||||
|
if (proc == 7) tipoProceso = 'MANIOBRAS ARCOSA' |
||||||
|
return tipoProceso |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Card> |
||||||
|
<Card.Body> |
||||||
|
<div className='row'> |
||||||
|
<div className='col-md-4'></div> |
||||||
|
<div className='col-md-2'> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
name='Referencia' |
||||||
|
placeholder='Proporcione la referencia' |
||||||
|
title='Inicio' |
||||||
|
alt='Inicio' |
||||||
|
data-date-format='YYYY-mm-dd' |
||||||
|
onChange={(e) => setReferencia(e.target.value)} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
<div className='col'> |
||||||
|
<Button |
||||||
|
variant='primary' |
||||||
|
onClick={() => { |
||||||
|
getPictureInfo() |
||||||
|
}} |
||||||
|
> |
||||||
|
Ver fotos |
||||||
|
</Button> |
||||||
|
</div> |
||||||
|
<div className='col-md-4'></div> |
||||||
|
</div> |
||||||
|
</Card.Body> |
||||||
|
</Card> |
||||||
|
<br /> |
||||||
|
<div> |
||||||
|
<Container> |
||||||
|
<Row xs={1} md={3} className='g-4'> |
||||||
|
{FileList |
||||||
|
? FileList.map((picture, index) => ( |
||||||
|
<Col> |
||||||
|
<Card style={{ width: '18rem' }}> |
||||||
|
<Card.Header className='text-center'>{picture.creado}</Card.Header> |
||||||
|
<Card.Body> |
||||||
|
<Card.Img |
||||||
|
variant='top' |
||||||
|
src={`${API + picture.nombre}`} |
||||||
|
onClick={() => showFullSize(picture.nombre)} |
||||||
|
/> |
||||||
|
<h6 className='text-center'>{picture.comentarios}</h6> |
||||||
|
</Card.Body> |
||||||
|
<Card.Footer className='text-center' as='h5'> |
||||||
|
{getProcessName(picture.proceso)} |
||||||
|
</Card.Footer> |
||||||
|
</Card> |
||||||
|
</Col> |
||||||
|
)) |
||||||
|
: null} |
||||||
|
</Row> |
||||||
|
</Container> |
||||||
|
</div> |
||||||
|
<Modal show={show} centered={true} animation={true} onHide={() => setShow(false)} contentClassName='image-modal'> |
||||||
|
<Modal.Header closeButton> |
||||||
|
<Modal.Title id='example-custom-modal-styling-title'></Modal.Title> |
||||||
|
</Modal.Header> |
||||||
|
<Modal.Body> |
||||||
|
<img src={`${API + imageFullSize}`} width='750' height='1000' className='justify-content-center' /> |
||||||
|
</Modal.Body> |
||||||
|
</Modal> |
||||||
|
<MsgInformativo |
||||||
|
show={MsgShow} |
||||||
|
msg={MsgTxt} |
||||||
|
header={MsgAlerta} |
||||||
|
msgColor={MsgColor} |
||||||
|
closeToast={function (arg: boolean): void { |
||||||
|
setMsgShow(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
import React, { FC, useState } from 'react' |
||||||
|
import { ContinuousQrScanner } from 'react-webcam-qr-scanner.ts' |
||||||
|
|
||||||
|
interface IProps {} |
||||||
|
|
||||||
|
/** |
||||||
|
* @author |
||||||
|
* @function @QRScanner |
||||||
|
**/ |
||||||
|
|
||||||
|
export const QRScanner: FC<IProps> = (props) => { |
||||||
|
const [qrCode, setQrCode] = useState('') |
||||||
|
const [shouldScan, setShouldScan] = useState(false) |
||||||
|
|
||||||
|
function startScanner() { |
||||||
|
setShouldScan(true) |
||||||
|
} |
||||||
|
function stopScanner() { |
||||||
|
setShouldScan(false) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
<p> |
||||||
|
QR Code: <code>{qrCode}</code> |
||||||
|
</p> |
||||||
|
{!shouldScan ? ( |
||||||
|
<button onClick={startScanner}>Scan QR Code</button> |
||||||
|
) : ( |
||||||
|
<> |
||||||
|
<button onClick={stopScanner}>Stop Scanning</button> |
||||||
|
{/* onQrCode can be fired multiple times */} |
||||||
|
<ContinuousQrScanner onQrCode={setQrCode} /> |
||||||
|
</> |
||||||
|
)} |
||||||
|
</> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,375 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import { Alert, Button, Card, Col, Form, Modal, Row } from 'react-bootstrap' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import ICatCorresponsales from '../../../Interfaces/Catalogos/ICatCorresponsales' |
||||||
|
import CorresponsalesDataService from '../../../Services/Catalogos/Corresponsales.Services' |
||||||
|
import { MsgInformativo } from '../../Utils/Toast/msgInformativo' |
||||||
|
import { useDispatch, useSelector } from 'react-redux' |
||||||
|
import { |
||||||
|
addCatCorresponsales, |
||||||
|
deleteCatCorresponsales, |
||||||
|
} from '../../../store/features/CatCorresponsales/CatCorresponsalesSlice' |
||||||
|
import { RootState } from '../../../store/store' |
||||||
|
import DataTable from 'react-data-table-component' |
||||||
|
import { ControlledInput } from './ControlledInput/ControlledInput' |
||||||
|
import { FaEraser, FaTimesCircle } from 'react-icons/fa' |
||||||
|
import * as CurrencyFormat from 'react-currency-format' |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
canDelete: boolean |
||||||
|
} |
||||||
|
|
||||||
|
export const CatCorresponsales: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch() |
||||||
|
const [Depto, setDepto] = useState(() => { |
||||||
|
const stickyValue = window.localStorage.getItem('Departamento') |
||||||
|
return stickyValue !== null ? JSON.parse(stickyValue) : '' |
||||||
|
}) |
||||||
|
const [filteredData, setFilteredData] = useState<ICatCorresponsales[]>([]) |
||||||
|
const mCorresponsales = useSelector((state: RootState) => state.CatCorresponsales.CatCorresponsales) |
||||||
|
// const gridRef = React.useRef<any>(null)
|
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msgColor, setMsgColor] = React.useState('primary') |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
const [id, setId] = useState(0) |
||||||
|
const [msgDialog, setMsgDialog] = useState(false) |
||||||
|
// const [IDCorresponsal, setIDCorresponsal] = useState(0)
|
||||||
|
const [Nombre, setNombre] = useState('') |
||||||
|
const [Patente, setPatente] = useState(0) |
||||||
|
const [Aduana, setAduana] = useState(0) |
||||||
|
const [Correos, setCorreos] = useState('') |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
CorresponsalesDataService.getAll() |
||||||
|
.then((response) => { |
||||||
|
setFilteredData(response.data) |
||||||
|
console.log(response.data) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
}, []) |
||||||
|
|
||||||
|
const columnsCorresponsales = [ |
||||||
|
{ |
||||||
|
name: 'id', |
||||||
|
width: '5%', |
||||||
|
selector: (row: ICatCorresponsales) => row.id, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Corresponsal ...................................................................................................................................... Patente ...... Aduana ...... Correos', |
||||||
|
width: '90%', |
||||||
|
cell: (row: ICatCorresponsales) => <ControlledInput record={row} />, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Elimina', |
||||||
|
width: '5%', |
||||||
|
cell: (row: ICatCorresponsales) => ( |
||||||
|
<div |
||||||
|
style={{ textAlign: 'center', cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
setId(row.id) |
||||||
|
setNombre(row.nombre) |
||||||
|
setPatente(row.patente) |
||||||
|
setAduana(row.aduana) |
||||||
|
setCorreos(row.correos) |
||||||
|
setMsgDialog(true) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'red', size: '25px' }}> |
||||||
|
<FaTimesCircle /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
), |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
function deleteRow(row: ICatCorresponsales) { |
||||||
|
setId(row.id) |
||||||
|
setNombre(row.nombre) |
||||||
|
setPatente(row.patente) |
||||||
|
setAduana(row.aduana) |
||||||
|
setMsgDialog(true) |
||||||
|
} |
||||||
|
|
||||||
|
const loadRow = (data: ICatCorresponsales) => { |
||||||
|
setId(data.id) |
||||||
|
setNombre(data.nombre) |
||||||
|
setPatente(data.patente) |
||||||
|
setAduana(data.aduana) |
||||||
|
setCorreos(data.correos) |
||||||
|
} |
||||||
|
|
||||||
|
function Guardar() { |
||||||
|
if (Patente < 999) { |
||||||
|
setHeader('Error!') |
||||||
|
setMsgColor('danger') |
||||||
|
setMsg('La patente debe tener 4 digitos') |
||||||
|
setShowMsg(true) |
||||||
|
return false |
||||||
|
} |
||||||
|
if (Aduana < 99) { |
||||||
|
setHeader('Error!') |
||||||
|
setMsgColor('danger') |
||||||
|
setMsg('La aduana debe tener 3 digitos') |
||||||
|
setShowMsg(true) |
||||||
|
return false |
||||||
|
} |
||||||
|
const data: ICatCorresponsales = { |
||||||
|
id: id, |
||||||
|
nombre: Nombre, |
||||||
|
aduana: Aduana, |
||||||
|
patente: Patente, |
||||||
|
correos: Correos, |
||||||
|
} |
||||||
|
CorresponsalesDataService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
if (response.status == 200) { |
||||||
|
dispatch(addCatCorresponsales(response.data)) |
||||||
|
setMsgColor('primary') |
||||||
|
setHeader('Confirmacion') |
||||||
|
setMsg('La informacion se guardo exitosamente') |
||||||
|
setShowMsg(true) |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
function cleanForm() { |
||||||
|
setId(0) |
||||||
|
setNombre('') |
||||||
|
setPatente(0) |
||||||
|
setAduana(0) |
||||||
|
} |
||||||
|
|
||||||
|
const deleteItem = () => { |
||||||
|
setMsgDialog(false) |
||||||
|
CorresponsalesDataService.Delete(id) |
||||||
|
.then((response) => { |
||||||
|
if (response.status == 200) { |
||||||
|
dispatch(deleteCatCorresponsales(id)) |
||||||
|
cleanForm() |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
|
||||||
|
setNombre('') |
||||||
|
setId(0) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Card className='labelSize13px'> |
||||||
|
<Card.Body> |
||||||
|
<Row |
||||||
|
style={{ |
||||||
|
visibility: props.canDelete ? 'visible' : 'hidden', |
||||||
|
height: props.canDelete ? '' : '0px', |
||||||
|
}} |
||||||
|
> |
||||||
|
<Col xs={1}> |
||||||
|
<Form.Label>Corresponsal</Form.Label> |
||||||
|
</Col> |
||||||
|
<Col xs={5}> |
||||||
|
{/* <Form.Control |
||||||
|
type='text' |
||||||
|
id='Nombre' |
||||||
|
size='sm' |
||||||
|
value={Nombre} |
||||||
|
pattern='[a-zA-Z ]*' |
||||||
|
onChange={(e) => setNombre((v) => (e.target.validity.valid ? e.target.value : v))} |
||||||
|
/> */} |
||||||
|
<input |
||||||
|
type='text' |
||||||
|
className='form-control genericSelect' |
||||||
|
name='Nombre' |
||||||
|
id='Nombre' |
||||||
|
style={{ height: '30px' }} |
||||||
|
value={Nombre} |
||||||
|
placeholder='Proporcione el nombre del corresponsal' |
||||||
|
onChange={(e) => { |
||||||
|
setNombre(e.target.value) |
||||||
|
}} |
||||||
|
/* onKeyDown={(e) => handleKeyDown(e)} */ |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={1}> |
||||||
|
<Form.Label>Correos</Form.Label> |
||||||
|
</Col> |
||||||
|
<Col xs={5}> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
id='Correos' |
||||||
|
size='sm' |
||||||
|
value={Correos} |
||||||
|
onChange={(e) => setCorreos((v) => e.target.value)} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row |
||||||
|
style={{ |
||||||
|
paddingTop: 5, |
||||||
|
visibility: props.canDelete ? 'visible' : 'hidden', |
||||||
|
height: props.canDelete ? '' : '0px', |
||||||
|
}} |
||||||
|
> |
||||||
|
<Col |
||||||
|
xs={1} |
||||||
|
style={{ textAlign: 'right', paddingTop: '5px', cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
cleanForm() |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'orange', size: '25px' }}> |
||||||
|
<FaEraser /> |
||||||
|
</IconContext.Provider> |
||||||
|
</Col> |
||||||
|
<Col xs={2}> </Col> |
||||||
|
<Col> |
||||||
|
<Form.Label>Patente</Form.Label> |
||||||
|
</Col> |
||||||
|
<Col> |
||||||
|
<CurrencyFormat |
||||||
|
value={Patente} |
||||||
|
displayType={Depto === 'Corresponsalias' ? 'input' : 'text'} |
||||||
|
onValueChange={(values: any) => { |
||||||
|
const { formattedValue, value } = values |
||||||
|
setPatente(value) |
||||||
|
}} |
||||||
|
style={ |
||||||
|
Depto === 'Corresponsalias' |
||||||
|
? { |
||||||
|
fontSize: '18px', |
||||||
|
backgroundColor: '#F5FFED', |
||||||
|
border: '2px solid #25D05B', |
||||||
|
width: '80px', |
||||||
|
textAlign: 'right', |
||||||
|
borderRadius: '10px', |
||||||
|
} |
||||||
|
: { |
||||||
|
fontSize: '18px', |
||||||
|
backgroundColor: '#F5FFED', |
||||||
|
border: '2px solid #25D05B', |
||||||
|
width: '80px', |
||||||
|
textAlign: 'right', |
||||||
|
borderRadius: '10px', |
||||||
|
paddingRight: '5px', |
||||||
|
paddingLeft: '5px', |
||||||
|
} |
||||||
|
} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col> </Col> |
||||||
|
<Col> |
||||||
|
<Form.Label>Aduana</Form.Label> |
||||||
|
</Col> |
||||||
|
<Col> |
||||||
|
<CurrencyFormat |
||||||
|
value={Aduana} |
||||||
|
displayType={Depto === 'Corresponsalias' ? 'input' : 'text'} |
||||||
|
onValueChange={(values: any) => { |
||||||
|
const { formattedValue, value } = values |
||||||
|
setAduana(value) |
||||||
|
}} |
||||||
|
style={ |
||||||
|
Depto === 'Corresponsalias' |
||||||
|
? { |
||||||
|
fontSize: '18px', |
||||||
|
backgroundColor: '#F5FFED', |
||||||
|
border: '2px solid #25D05B', |
||||||
|
width: '60px', |
||||||
|
textAlign: 'right', |
||||||
|
borderRadius: '10px', |
||||||
|
} |
||||||
|
: { |
||||||
|
fontSize: '18px', |
||||||
|
backgroundColor: '#F5FFED', |
||||||
|
border: '2px solid #25D05B', |
||||||
|
width: '60px', |
||||||
|
textAlign: 'right', |
||||||
|
borderRadius: '10px', |
||||||
|
paddingRight: '5px', |
||||||
|
paddingLeft: '5px', |
||||||
|
} |
||||||
|
} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={2}></Col> |
||||||
|
<Col md='auto'> |
||||||
|
<Button |
||||||
|
variant='primary' |
||||||
|
size='sm' |
||||||
|
onClick={() => { |
||||||
|
Guardar() |
||||||
|
}} |
||||||
|
> |
||||||
|
Guardar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row style={{ paddingTop: 5 }}> |
||||||
|
<DataTable |
||||||
|
noHeader |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={columnsCorresponsales} |
||||||
|
data={mCorresponsales} |
||||||
|
/> |
||||||
|
<Col></Col> |
||||||
|
</Row> |
||||||
|
</Card.Body> |
||||||
|
</Card> |
||||||
|
<Modal show={msgDialog} onHide={() => setMsgDialog(false)} size='sm'> |
||||||
|
<Modal.Body> |
||||||
|
<Alert variant='primary'> |
||||||
|
<b>¿Esta seguro de eliminar?</b> |
||||||
|
<br /> |
||||||
|
<h5> |
||||||
|
{Nombre} | Patente: {Patente} | Aduana {Aduana} |
||||||
|
</h5> |
||||||
|
</Alert> |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={6}> |
||||||
|
<Button variant='secondary' onClick={() => setMsgDialog(false)} size='sm'> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={6}> |
||||||
|
<Button variant='primary' onClick={deleteItem} size='sm'> |
||||||
|
Si |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Footer> |
||||||
|
</Modal> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,114 @@ |
|||||||
|
import React, { FC, useState } from 'react' |
||||||
|
import { useDispatch } from 'react-redux' |
||||||
|
import ICatCorresponsales from '../../../../Interfaces/Catalogos/ICatCorresponsales' |
||||||
|
import CorDataService from '../../../../Services/Catalogos/Corresponsales.Services' |
||||||
|
import { updateCatCorresponsales } from '../../../../store/features/CatCorresponsales/CatCorresponsalesSlice' |
||||||
|
import { MsgInformativo } from '../../../Utils/Toast/msgInformativo' |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
record: ICatCorresponsales |
||||||
|
} |
||||||
|
|
||||||
|
export const ControlledInput: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch() |
||||||
|
const [IDCorresponsal, setIDCorresponsal] = useState(props.record.id) |
||||||
|
const [Corresponsal, setCorresponsal] = useState(props.record.nombre) |
||||||
|
const [Patente, setPatente] = useState(props.record.patente) |
||||||
|
const [Aduana, setAduana] = useState(props.record.aduana) |
||||||
|
const [Correos, setCorreos] = useState(props.record.correos) |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msgColor, setMsgColor] = React.useState('primary') |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
|
||||||
|
const onChangeCor = (event: any) => { |
||||||
|
setCorresponsal(event.target.value) |
||||||
|
} |
||||||
|
|
||||||
|
const onChangeAd = (event: any) => { |
||||||
|
setAduana(event.target.value) |
||||||
|
} |
||||||
|
const onChangePat = (event: any) => { |
||||||
|
setPatente(event.target.value) |
||||||
|
} |
||||||
|
const onChangeEmail = (event: any) => { |
||||||
|
setCorreos(event.target.value) |
||||||
|
} |
||||||
|
|
||||||
|
const handleKeyDown = (event: any, mode: number) => { |
||||||
|
if (event.key === 'Enter') { |
||||||
|
if (isNaN(event.target.value) && mode === 1) { |
||||||
|
alert('Valor no valido!') |
||||||
|
return |
||||||
|
} |
||||||
|
const data: ICatCorresponsales = { |
||||||
|
id: props.record.id, |
||||||
|
nombre: Corresponsal, |
||||||
|
patente: Patente, |
||||||
|
aduana: Aduana, |
||||||
|
correos: Correos, |
||||||
|
} |
||||||
|
CorDataService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
if (response.status == 200) { |
||||||
|
dispatch(updateCatCorresponsales(response.data)) |
||||||
|
setHeader('Informativo') |
||||||
|
setMsg('La informacion se guardo exitosamente') |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<input |
||||||
|
value={Corresponsal} |
||||||
|
onChange={onChangeCor} |
||||||
|
disabled={false} |
||||||
|
onKeyDown={(e) => handleKeyDown(e, 2)} |
||||||
|
style={{ width: '450px', textAlign: 'left' }} |
||||||
|
/> |
||||||
|
|
||||||
|
<input |
||||||
|
value={Patente} |
||||||
|
onChange={onChangePat} |
||||||
|
disabled={false} |
||||||
|
onKeyDown={(e) => handleKeyDown(e, 1)} |
||||||
|
style={{ width: '50px', textAlign: 'right' }} |
||||||
|
/> |
||||||
|
|
||||||
|
<input |
||||||
|
value={Aduana} |
||||||
|
onChange={onChangeAd} |
||||||
|
disabled={false} |
||||||
|
onKeyDown={(e) => handleKeyDown(e, 1)} |
||||||
|
style={{ width: '30px', textAlign: 'right' }} |
||||||
|
/> |
||||||
|
|
||||||
|
<input |
||||||
|
value={Correos} |
||||||
|
onChange={onChangeEmail} |
||||||
|
disabled={false} |
||||||
|
onKeyDown={(e) => handleKeyDown(e, 2)} |
||||||
|
style={{ width: '650px', textAlign: 'left' }} |
||||||
|
/> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,501 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
|
||||||
|
import ITabulador from '../../../Interfaces/Catalogos/ITabulador' |
||||||
|
import ITabuladorConceptos from '../../../Interfaces/Catalogos/ITabuladorConceptos' |
||||||
|
import DTOConceptos from '../../../DTO/Utils/DTOConceptos' |
||||||
|
|
||||||
|
import CTabDataService from '../../../Services/Corresponsalias/Corresponsales.Tabuladores.Services' |
||||||
|
import CTabDetDataService from '../../../Services/Corresponsalias/Corresponsales.Tabuladores.Detalle.Sevices' |
||||||
|
import ClientesDataService from '../../../Services/Catalogos/Clientes.Services' |
||||||
|
|
||||||
|
import { MsgInformativo } from '../../Utils/Toast/msgInformativo' |
||||||
|
import { ControlledInput } from '../../Utils/ControlledInput/ControlledInput' |
||||||
|
import DataTable from 'react-data-table-component' |
||||||
|
import { Alert, Button, Card, Col, Container, Form, Modal, Row } from 'react-bootstrap' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import 'react-data-table-component-extensions/dist/index.css' |
||||||
|
import { BsPlusSquareFill } from 'react-icons/bs' |
||||||
|
import IClientes from '../../../Interfaces/Catalogos/IClientes' |
||||||
|
import { FcTimeline } from 'react-icons/fc' |
||||||
|
import { FaEraser, FaTimesCircle } from 'react-icons/fa' |
||||||
|
|
||||||
|
interface IProps {} |
||||||
|
|
||||||
|
interface IselectedRows { |
||||||
|
allSelected: boolean |
||||||
|
selectedCount: number |
||||||
|
selectedRows: any |
||||||
|
} |
||||||
|
|
||||||
|
export const CatTabuladores: FC<IProps> = (props) => { |
||||||
|
const [UserId, setUserId] = useState(() => { |
||||||
|
const stickyValue = window.localStorage.getItem('UserId') |
||||||
|
return stickyValue !== null ? JSON.parse(stickyValue) : 0 |
||||||
|
}) |
||||||
|
const [Tabulador, setTabulador] = useState(0) |
||||||
|
const [Concepto, setConcepto] = useState(0) |
||||||
|
const [Cliente, setCliente] = useState(0) |
||||||
|
const [Clientes, setClientes] = useState<Array<IClientes>>() |
||||||
|
const [NombreTabulador, setNombreTabulador] = useState('') |
||||||
|
const [DetalleConceptos, setDetalleConceptos] = useState<ITabuladorConceptos[]>([]) |
||||||
|
const [CatConceptos, setCatConceptos] = useState<DTOConceptos[]>([]) |
||||||
|
const [Tabuladores, setTabuladores] = useState<ITabulador[]>([]) |
||||||
|
const [AllTabuladores, setAllTabuladores] = useState<ITabulador[]>([]) |
||||||
|
const [Costo, setCosto] = useState('') |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msgColor, setMsgColor] = React.useState('primary') |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
const [DialogTabs, setDialogTabs] = useState(false) |
||||||
|
|
||||||
|
const columnsConcepts = [ |
||||||
|
{ |
||||||
|
name: 'id', |
||||||
|
selector: (row: ITabuladorConceptos) => row.id, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Concepto', |
||||||
|
width: '70%', |
||||||
|
selector: (row: ITabuladorConceptos) => row.concepto, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Costo', |
||||||
|
cell: (row: ITabuladorConceptos) => ( |
||||||
|
<ControlledInput |
||||||
|
id={row.id} |
||||||
|
value={row.costo} |
||||||
|
postCost={(id, value) => { |
||||||
|
postCost(id, value) |
||||||
|
}} |
||||||
|
/> |
||||||
|
), |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
const columnsTabs = [ |
||||||
|
{ |
||||||
|
name: 'id', |
||||||
|
selector: (row: ITabulador) => row.id, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Nombre', |
||||||
|
width: '70%', |
||||||
|
cell: (row: ITabulador) => ( |
||||||
|
<div |
||||||
|
style={{ width: '450px', cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
setTabulador(row.id) |
||||||
|
setNombreTabulador(row.nombre) |
||||||
|
}} |
||||||
|
> |
||||||
|
{row.nombre} |
||||||
|
</div> |
||||||
|
), |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Elimina', |
||||||
|
cell: (row: ITabulador) => ( |
||||||
|
<div |
||||||
|
style={{ textAlign: 'center', cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
setTabulador(row.id) |
||||||
|
setNombreTabulador(row.nombre) |
||||||
|
setDialogTabs(true) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'red', size: '25px' }}> |
||||||
|
<FaTimesCircle /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
), |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
const postCost = (id: number, Cost: number) => { |
||||||
|
const data: ITabuladorConceptos = { |
||||||
|
id: id, |
||||||
|
idTabulador: Tabulador, |
||||||
|
idConcepto: Concepto, |
||||||
|
concepto: '', |
||||||
|
costo: Cost, |
||||||
|
activo: 1, |
||||||
|
} |
||||||
|
CTabDetDataService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
setDetalleConceptos(response.data) |
||||||
|
setHeader('Confirmacion') |
||||||
|
setMsg('La informacion se guardo corrctamente') |
||||||
|
setShowMsg(true) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const deleteTabulador = () => { |
||||||
|
CTabDataService.Delete(Tabulador) |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
setHeader('Informativo') |
||||||
|
setMsg(response.data.respuesta) |
||||||
|
setShowMsg(true) |
||||||
|
setDialogTabs(false) |
||||||
|
setTabuladores(Tabuladores.filter((data) => data.id != Tabulador)) |
||||||
|
setAllTabuladores(Tabuladores) |
||||||
|
return |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
CTabDetDataService.getAllConcepts() |
||||||
|
.then((response) => { |
||||||
|
setCatConceptos(response.data) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
ClientesDataService.getAllClientes(UserId) |
||||||
|
.then((response) => { |
||||||
|
setClientes(response.data) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
}, []) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
CTabDetDataService.GetDetailByIdTab(Tabulador) |
||||||
|
.then((response) => { |
||||||
|
setDetalleConceptos(response.data) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
console.log(Tabulador) |
||||||
|
}, [Tabulador]) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (Cliente > 0) { |
||||||
|
setNombreTabulador('') |
||||||
|
setTabuladores([]) |
||||||
|
setDetalleConceptos([]) |
||||||
|
CTabDataService.GetByCustomer(Cliente) |
||||||
|
.then((response) => { |
||||||
|
setTabuladores(response.data) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
}, [Cliente]) |
||||||
|
|
||||||
|
const filtraTabulador = (e: any) => { |
||||||
|
if (e.target.value !== '') { |
||||||
|
setTabuladores( |
||||||
|
AllTabuladores.filter(function (el) { |
||||||
|
return el.nombre.toLocaleLowerCase().includes(e.target.value.toLocaleLowerCase()) |
||||||
|
}) |
||||||
|
) |
||||||
|
} else { |
||||||
|
setTabuladores(AllTabuladores) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const saveForm = () => { |
||||||
|
const data: ITabulador = { |
||||||
|
id: Tabulador, |
||||||
|
idCliente: Cliente, |
||||||
|
nombre: NombreTabulador, |
||||||
|
} |
||||||
|
CTabDataService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
setHeader('Informativo') |
||||||
|
setMsg('La informacion se guardo correctamente') |
||||||
|
setShowMsg(true) |
||||||
|
if (Tabulador > 0) { |
||||||
|
let tmp = Tabuladores |
||||||
|
let idx = tmp.findIndex((obj) => obj.id == Tabulador) |
||||||
|
tmp[idx].nombre = NombreTabulador |
||||||
|
setTabuladores(tmp) |
||||||
|
setAllTabuladores(tmp) |
||||||
|
} else { |
||||||
|
setTabulador(response.data.id) |
||||||
|
const tmp = [...Tabuladores, response.data] |
||||||
|
setTabuladores(tmp) |
||||||
|
setAllTabuladores(tmp) |
||||||
|
} |
||||||
|
return |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const addConcept = () => { |
||||||
|
if (Tabulador === 0) { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Por favor, primero seleccione el tabulador') |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
} |
||||||
|
if (Concepto === 0) { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Por favor, primero seleccione el concepto') |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
} |
||||||
|
postCost(0, 0) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Card> |
||||||
|
<Card.Body> |
||||||
|
<Card style={{ height: '100%' }}> |
||||||
|
<Card.Header as='h4'>Tabuladores</Card.Header> |
||||||
|
<Card.Body> |
||||||
|
<Container fluid> |
||||||
|
<Alert variant='primary'> |
||||||
|
<Row> |
||||||
|
<Col xs={1} style={{ paddingTop: '5px' }}> |
||||||
|
<h5>Cliente: </h5> |
||||||
|
</Col> |
||||||
|
<Col xs={5}> |
||||||
|
<h4> |
||||||
|
<Form.Control |
||||||
|
as='select' |
||||||
|
onChange={(e) => { |
||||||
|
setCliente(parseInt(e.target.value)) |
||||||
|
}} |
||||||
|
className='form-select form-select-sm' |
||||||
|
style={{ fontSize: '18px' }} |
||||||
|
> |
||||||
|
<option value='0'>-SELECCIONE-</option> |
||||||
|
{Clientes |
||||||
|
? Clientes.map((c) => { |
||||||
|
return ( |
||||||
|
<option value={c.sClave} key={c.sClave}> |
||||||
|
{c.sRazonSocial} |
||||||
|
</option> |
||||||
|
) |
||||||
|
}) |
||||||
|
: null} |
||||||
|
</Form.Control> |
||||||
|
</h4> |
||||||
|
</Col> |
||||||
|
<Col |
||||||
|
xs={1} |
||||||
|
style={{ textAlign: 'right', paddingTop: '5px', cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
setTabulador(0) |
||||||
|
setNombreTabulador('') |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'orange', size: '25px' }}> |
||||||
|
<FaEraser /> |
||||||
|
</IconContext.Provider> |
||||||
|
</Col> |
||||||
|
<Col xs={1} style={{ paddingTop: '5px' }}> |
||||||
|
<div> |
||||||
|
<h5>Tabulador</h5> |
||||||
|
</div> |
||||||
|
</Col> |
||||||
|
<Col xs={3}> |
||||||
|
<h4> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
id='NombreTabulador' |
||||||
|
size='sm' |
||||||
|
value={NombreTabulador} |
||||||
|
onChange={(e) => { |
||||||
|
setNombreTabulador(e.target.value) |
||||||
|
}} |
||||||
|
placeholder='Nombre del tabulador' |
||||||
|
style={{ fontSize: '18px' }} |
||||||
|
/> |
||||||
|
</h4> |
||||||
|
</Col> |
||||||
|
<Col> |
||||||
|
<Button |
||||||
|
variant='primary' |
||||||
|
size='sm' |
||||||
|
style={{ paddingLeft: '10px', paddingRight: '10px' }} |
||||||
|
onClick={() => saveForm()} |
||||||
|
> |
||||||
|
Guardar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Alert> |
||||||
|
<Row> |
||||||
|
<Col xs={6}> |
||||||
|
<Card style={{}}> |
||||||
|
<Card.Body> |
||||||
|
<Card.Subtitle className='mb-2 text-muted'> |
||||||
|
<Row> |
||||||
|
<Col xs={2} style={{ paddingTop: '8px' }}> |
||||||
|
Tabulador |
||||||
|
</Col> |
||||||
|
<Col xs={10}> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
size='sm' |
||||||
|
placeholder='Busqueda de tabulador...' |
||||||
|
onChange={(e) => { |
||||||
|
filtraTabulador(e) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Card.Subtitle> |
||||||
|
<DataTable |
||||||
|
noHeader |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={columnsTabs} |
||||||
|
data={Tabuladores} |
||||||
|
/> |
||||||
|
</Card.Body> |
||||||
|
</Card> |
||||||
|
</Col> |
||||||
|
<Col xs={6}> |
||||||
|
<Card style={{}}> |
||||||
|
<Card.Body> |
||||||
|
<Card.Subtitle className='mb-2 text-muted'> |
||||||
|
<Row> |
||||||
|
<Col xs={2} style={{ paddingTop: '8px' }}> |
||||||
|
Conceptos |
||||||
|
</Col> |
||||||
|
<Col xs={9}> |
||||||
|
<Form.Control |
||||||
|
as='select' |
||||||
|
onChange={(e) => setConcepto(parseInt(e.target.value))} |
||||||
|
className='form-select form-select-sm' |
||||||
|
style={{ fontSize: '17px' }} |
||||||
|
> |
||||||
|
<option value='0'>- Seleccione -</option> |
||||||
|
{CatConceptos |
||||||
|
? CatConceptos.map((c) => { |
||||||
|
return ( |
||||||
|
<option value={c.id} key={c.id}> |
||||||
|
{c.concepto} |
||||||
|
</option> |
||||||
|
) |
||||||
|
}) |
||||||
|
: null} |
||||||
|
</Form.Control> |
||||||
|
</Col> |
||||||
|
<Col style={{ paddingTop: '5px' }}> |
||||||
|
<Form.Label |
||||||
|
onClick={() => { |
||||||
|
addConcept() |
||||||
|
}} |
||||||
|
style={{ cursor: 'pointer' }} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'green', size: '30px' }}> |
||||||
|
<BsPlusSquareFill /> |
||||||
|
</IconContext.Provider> |
||||||
|
</Form.Label> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Card.Subtitle> |
||||||
|
<DataTable |
||||||
|
noHeader |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={columnsConcepts} |
||||||
|
data={DetalleConceptos} |
||||||
|
/> |
||||||
|
</Card.Body> |
||||||
|
</Card> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Container> |
||||||
|
</Card.Body> |
||||||
|
</Card> |
||||||
|
</Card.Body> |
||||||
|
</Card> |
||||||
|
<Modal |
||||||
|
show={DialogTabs} |
||||||
|
onHide={() => { |
||||||
|
setDialogTabs(false) |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
<Modal.Body> |
||||||
|
¿Esta seguro de eliminar: |
||||||
|
<br /> {NombreTabulador}? |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={6} style={{ textAlign: 'left', paddingRight: '100px' }}> |
||||||
|
<Button |
||||||
|
variant='danger' |
||||||
|
onClick={deleteTabulador} |
||||||
|
size='sm' |
||||||
|
style={{ paddingRight: '20px', paddingLeft: '20px' }} |
||||||
|
> |
||||||
|
Si |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={6} style={{ textAlign: 'right' }}> |
||||||
|
<Button |
||||||
|
variant='secondary' |
||||||
|
onClick={() => { |
||||||
|
setDialogTabs(false) |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Footer> |
||||||
|
</Modal> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,253 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import { useParams } from 'react-router-dom' |
||||||
|
import '../../../../css/printableArea.css' |
||||||
|
import I325Pedidos from '../../../../Interfaces/Clientes/CasaCuervo/I325Pedidos' |
||||||
|
import PedDataService from '../../../../Services/Clientes/CasaCuervo/Pedidos.Services' |
||||||
|
|
||||||
|
interface IProps {} |
||||||
|
|
||||||
|
interface IMedidaCaja { |
||||||
|
id: number |
||||||
|
Medida: string |
||||||
|
} |
||||||
|
|
||||||
|
export const FormatoRevision: FC<IProps> = (props) => { |
||||||
|
const { id } = useParams() |
||||||
|
const [ID, setID] = useState<number>(0) |
||||||
|
const [Data, setData] = useState<I325Pedidos>() |
||||||
|
|
||||||
|
const mCatMedidas: IMedidaCaja[] = [ |
||||||
|
{ id: 0, Medida: 'SELECCIONE' }, |
||||||
|
{ id: 1, Medida: 'Caja 53 pies' }, |
||||||
|
{ id: 2, Medida: 'Caja 48 pies' }, |
||||||
|
{ id: 3, Medida: 'Refrigerada 53 pies' }, |
||||||
|
{ id: 4, Medida: 'Pipa' }, |
||||||
|
] |
||||||
|
|
||||||
|
const Print = () => { |
||||||
|
let printContents: string = (document.getElementById('printableDiv') as HTMLInputElement).innerHTML |
||||||
|
let originalContents = document.body.innerHTML |
||||||
|
document.body.innerHTML = printContents |
||||||
|
window.print() |
||||||
|
document.body.innerHTML = originalContents |
||||||
|
} |
||||||
|
|
||||||
|
const GetID = () => { |
||||||
|
let Id: string = id ?? '0' |
||||||
|
return parseInt(Id) |
||||||
|
} |
||||||
|
|
||||||
|
const loadData = () => { |
||||||
|
PedDataService.GetById(GetID()) |
||||||
|
.then((response) => { |
||||||
|
setData(response.data) |
||||||
|
Print() |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
return false |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
/* useEffect(() => { |
||||||
|
Print() |
||||||
|
}, []) */ |
||||||
|
|
||||||
|
const GetCurrentDateTime = () => { |
||||||
|
var today = new Date() |
||||||
|
var date = |
||||||
|
today.getDate().toString().padStart(2, '0') + |
||||||
|
'-' + |
||||||
|
(today.getMonth() + 1).toString().padStart(2, '0') + |
||||||
|
'-' + |
||||||
|
today.getFullYear() |
||||||
|
var time = |
||||||
|
today.getHours() + |
||||||
|
':' + |
||||||
|
today.getMinutes().toString().padStart(2, '0') + |
||||||
|
':' + |
||||||
|
today.getSeconds().toString().padStart(2, '0') |
||||||
|
var dateTime = date + ' ' + time |
||||||
|
return dateTime |
||||||
|
} |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
loadData() |
||||||
|
}, [id]) |
||||||
|
|
||||||
|
return ( |
||||||
|
<div id='printableDiv'> |
||||||
|
<div className='printableDiv'> |
||||||
|
<table> |
||||||
|
<tr> |
||||||
|
<th colSpan={6} style={{ textAlign: 'center', backgroundColor: '#FFFFFF' }}> |
||||||
|
Nota de revision de mercancia y sellos de seguridad: Casa Cuervo |
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td style={{ textAlign: 'right' }}> |
||||||
|
<span style={{ fontWeight: 'bold' }}>Fecha y hora de impresion: </span> |
||||||
|
{GetCurrentDateTime()} |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
|
||||||
|
<tr> |
||||||
|
<td> |
||||||
|
Sr Despachador / Tramitador |
||||||
|
<br /> |
||||||
|
1. Tomar sellos de seguridad |
||||||
|
<br /> |
||||||
|
2. Romper los sellos se seguridad de origen |
||||||
|
<br /> |
||||||
|
3. Abrir caja trailer y tomar fotos de la mercancia |
||||||
|
<br /> |
||||||
|
4. Vertificar numeros de lote contra factura |
||||||
|
<br /> |
||||||
|
5. Contar la cantidad de bultos |
||||||
|
<br /> |
||||||
|
6. Colocar la caja trailer y colocar nuevos sellos |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td>Si no se cuentra con sellos del cliente, poner sellos de GEMCO previa autorizacion del cliente</td> |
||||||
|
</tr> |
||||||
|
<tr style={{ width: '100%' }}> |
||||||
|
<th colSpan={6} style={{ backgroundColor: '#FFFFFF' }}> |
||||||
|
|
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td> |
||||||
|
<table style={{ width: '100%' }}> |
||||||
|
<tr> |
||||||
|
<td style={{ backgroundColor: '#FFFFFF', fontWeight: 'bold' }}>No. de pedido</td> |
||||||
|
<td style={{ backgroundColor: '#FFFFFF', fontWeight: 'bold' }}>No. de factura</td> |
||||||
|
<td style={{ backgroundColor: '#FFFFFF', fontWeight: 'bold' }}>Cartones</td> |
||||||
|
<td style={{ backgroundColor: '#FFFFFF', fontWeight: 'bold' }}>Bultos</td> |
||||||
|
<td style={{ backgroundColor: '#FFFFFF', fontWeight: 'bold' }}>No. de Caja</td> |
||||||
|
<td style={{ backgroundColor: '#FFFFFF', fontWeight: 'bold' }}>Medida de la caja</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td>{Data?.po}</td> |
||||||
|
<td>{Data?.factura}</td> |
||||||
|
<td> </td> |
||||||
|
<td> </td> |
||||||
|
<td>{Data?.truckNumber}</td> |
||||||
|
<td> |
||||||
|
{mCatMedidas |
||||||
|
? mCatMedidas.map((a) => { |
||||||
|
return Data?.medidaCaja === a.id.toString() ? a.Medida : '' |
||||||
|
}) |
||||||
|
: null} |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td> </td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td> |
||||||
|
<span style={{ fontWeight: 'bold' }}>Nombre de la linea: </span> |
||||||
|
{Data?.forwarder} |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td> |
||||||
|
<table style={{ width: '100%' }}> |
||||||
|
<tr> |
||||||
|
<th colSpan={6} style={{ textAlign: 'center', backgroundColor: '#FFFFFF' }}> |
||||||
|
Numero de sellos |
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td style={{ backgroundColor: '#FFFFFF', fontWeight: 'bold' }} width='30%'> |
||||||
|
Origen |
||||||
|
</td> |
||||||
|
<td style={{ backgroundColor: '#FFFFFF', fontWeight: 'bold' }} width='10%'> |
||||||
|
Izquierdo |
||||||
|
</td> |
||||||
|
<td style={{ backgroundColor: '#FFFFFF', fontWeight: 'bold' }} width='10%'> |
||||||
|
Derecho |
||||||
|
</td> |
||||||
|
<td style={{ backgroundColor: '#FFFFFF', fontWeight: 'bold' }} width='30%'> |
||||||
|
Nuevos despues de la revision |
||||||
|
</td> |
||||||
|
<td style={{ backgroundColor: '#FFFFFF', fontWeight: 'bold' }} width='10%'> |
||||||
|
Izquierdo |
||||||
|
</td> |
||||||
|
<td style={{ backgroundColor: '#FFFFFF', fontWeight: 'bold' }} width='10%'> |
||||||
|
Derecho |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td width='30%'>{Data?.sello1}</td> |
||||||
|
<td width='10%' style={{ backgroundColor: '#FFFFFF' }}> |
||||||
|
|
||||||
|
</td> |
||||||
|
<td width='10%'> </td> |
||||||
|
<td width='30%' style={{ backgroundColor: '#FFFFFF' }}> |
||||||
|
|
||||||
|
</td> |
||||||
|
<td width='10%'> </td> |
||||||
|
<td width='10%' style={{ backgroundColor: '#FFFFFF' }}> |
||||||
|
|
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td width='30%'>{Data?.sello2}</td> |
||||||
|
<td width='10%'> </td> |
||||||
|
<td width='10%'> </td> |
||||||
|
<td width='30%'> </td> |
||||||
|
<td width='10%'> </td> |
||||||
|
<td width='10%'> </td> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td> </td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<th colSpan={6} style={{ backgroundColor: '#FFFFFF' }}> |
||||||
|
Numero de placa y estado de Origen |
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td> </td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<th colSpan={6} style={{ backgroundColor: '#FFFFFF' }}> |
||||||
|
Condiciones de la caja o pipa |
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
<tr style={{ height: '90px' }}> |
||||||
|
<td> </td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<th colSpan={6} style={{ backgroundColor: '#FFFFFF' }}> |
||||||
|
Resultado de la revision de la mercancia |
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
<tr style={{ height: '90px' }}> |
||||||
|
<td> </td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td> |
||||||
|
<table style={{ width: '100%' }}> |
||||||
|
<tr> |
||||||
|
<td> </td> |
||||||
|
<td style={{ backgroundColor: '#FFFFFF' }}> </td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<th style={{ textAlign: 'center' }}>Nombre y firma del revisor</th> |
||||||
|
<th style={{ textAlign: 'center' }}>Fecha y hora de la revision</th> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,106 @@ |
|||||||
|
import React, { FC, useState } from 'react' |
||||||
|
import PedidosDataService from '../../../../../Services/Clientes/CasaCuervo/Pedidos.Services' |
||||||
|
import { Form } from 'react-bootstrap' |
||||||
|
//import Datetime from 'react-datetime'
|
||||||
|
//import 'react-datetime/css/react-datetime.css'
|
||||||
|
//import '../../../../../css/generic01.css'
|
||||||
|
import DatePicker from 'react-datepicker' |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
value: string |
||||||
|
mode: string |
||||||
|
IDPedido: number |
||||||
|
onUpdate: (valor: string) => void |
||||||
|
} |
||||||
|
|
||||||
|
export const ControlledInput: FC<IProps> = (props) => { |
||||||
|
//const dispatch = useDispatch()
|
||||||
|
const [value, setValue] = useState(props.value) |
||||||
|
const [valueDT, setValueDT] = useState(null) |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msgColor, setMsgColor] = React.useState('primary') |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
const [startDate, setStartDate] = useState(new Date()) |
||||||
|
|
||||||
|
const onChange = (event: any) => { |
||||||
|
setValue(event.target.value) |
||||||
|
} |
||||||
|
|
||||||
|
const DoStuff = (event: any) => { |
||||||
|
setValue(event.target.value) |
||||||
|
PedidosDataService.Update(props.IDPedido, props.mode, event.target.value) |
||||||
|
.then((response) => { |
||||||
|
if (response.status == 200) { |
||||||
|
setHeader('Informativo') |
||||||
|
setMsg('La informacion se guardo exitosamente') |
||||||
|
setShowMsg(true) |
||||||
|
props.onUpdate(event.target.value) |
||||||
|
return |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const handleKeyDown = (event: any) => { |
||||||
|
if (event.key === 'Enter') { |
||||||
|
if (value) { |
||||||
|
PedidosDataService.Update(props.IDPedido, props.mode, value) |
||||||
|
.then((response) => { |
||||||
|
if (response.status == 200) { |
||||||
|
setHeader('Informativo') |
||||||
|
setMsg('La informacion se guardo exitosamente') |
||||||
|
setShowMsg(true) |
||||||
|
props.onUpdate(value) |
||||||
|
return |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
{props.mode === 'estatus' || props.mode === 'comentarioGEMCO' ? ( |
||||||
|
<input value={value} onChange={onChange} onKeyDown={(e) => handleKeyDown(e)} style={{ width: '75%' }} /> |
||||||
|
) : ( |
||||||
|
/* <Form.Control |
||||||
|
defaultValue={value} |
||||||
|
type='date' |
||||||
|
name='Inicio' |
||||||
|
placeholder='Inicio' |
||||||
|
title='Inicio' |
||||||
|
alt='Inicio' |
||||||
|
data-date-format='YYYY-mm-dd' |
||||||
|
onChange={(e) => DoStuff(e)} |
||||||
|
size='sm' |
||||||
|
/> */ |
||||||
|
/* <Datetime |
||||||
|
input={true} |
||||||
|
initialValue={value} |
||||||
|
inputProps={{ placeholder: 'No definido', className: 'genericinput' }} |
||||||
|
onChange={(date: any) => setValue(date)} |
||||||
|
dateFormat='yyyy-MM-DD' |
||||||
|
/> */ |
||||||
|
<DatePicker |
||||||
|
selected={valueDT} |
||||||
|
onChange={(date: any) => setStartDate(date)} |
||||||
|
timeInputLabel='Time:' |
||||||
|
dateFormat='MM/dd/yyyy h:mm aa' |
||||||
|
showTimeInput |
||||||
|
/> |
||||||
|
)} |
||||||
|
</> |
||||||
|
) |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,105 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import { Form } from 'react-bootstrap' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import { BsX } from 'react-icons/bs' |
||||||
|
import IFileManager from '../../../../Interfaces/Utils/IFileManager' |
||||||
|
import MFileManagerDS from '../../../../Services/Utils/MFileManager.Service' |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
id: number |
||||||
|
docType: number |
||||||
|
} |
||||||
|
|
||||||
|
export const CmbArchivos: FC<IProps> = (props) => { |
||||||
|
const [Data, setData] = useState<IFileManager[]>([]) |
||||||
|
const [IDArchivo, setIDArchivo] = useState(0) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (props.id !== 0) { |
||||||
|
MFileManagerDS.Get(props.id, props.docType) |
||||||
|
.then((response) => { |
||||||
|
console.log(JSON.stringify(response.data)) |
||||||
|
setData(response.data) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
}, [props.id]) |
||||||
|
|
||||||
|
const viewFile = (e: any) => { |
||||||
|
setIDArchivo(parseInt(e.target.value)) |
||||||
|
getFileContent(parseInt(e.target.value), props.docType) |
||||||
|
} |
||||||
|
|
||||||
|
const getFileContent = (id: number, proceso: number) => { |
||||||
|
MFileManagerDS.getFileContentById(id, proceso) |
||||||
|
.then((response: any) => { |
||||||
|
if (response.status === 200) { |
||||||
|
let found = Data.filter((a) => { |
||||||
|
if (a.id == id) { |
||||||
|
return a |
||||||
|
} |
||||||
|
}) |
||||||
|
if (found[0].nombreArchivo.toLowerCase().endsWith('.pdf')) { |
||||||
|
// console.log(response.data)
|
||||||
|
const blob = new Blob([response.data], { type: 'application/pdf' }) |
||||||
|
const url = window.URL.createObjectURL(blob) |
||||||
|
window.open(url) |
||||||
|
} else if ( |
||||||
|
found[0].nombreArchivo.toLowerCase().endsWith('.png') || |
||||||
|
found[0].nombreArchivo.toLowerCase().endsWith('.jpg') |
||||||
|
) { |
||||||
|
const blob = new Blob([response.data], { type: 'image/png' }) |
||||||
|
const url = window.URL.createObjectURL(blob) |
||||||
|
window.open(url) |
||||||
|
} else { |
||||||
|
const url = window.URL.createObjectURL(new Blob([response.data])) |
||||||
|
const link = document.createElement('a') |
||||||
|
link.href = url |
||||||
|
link.setAttribute('download', found[0].nombreArchivo ? found[0].nombreArchivo : 'Archivo.zip') |
||||||
|
document.body.appendChild(link) |
||||||
|
link.click() |
||||||
|
} |
||||||
|
} else { |
||||||
|
return |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div style={{ textAlign: 'center' }}> |
||||||
|
{Data.length > 0 ? ( |
||||||
|
<> |
||||||
|
<Form.Control |
||||||
|
as='select' |
||||||
|
onChange={(e) => { |
||||||
|
viewFile(e) |
||||||
|
}} |
||||||
|
className='form-select form-select-sm' |
||||||
|
> |
||||||
|
<option value='0'>-SELECCIONE-</option> |
||||||
|
{Data |
||||||
|
? Data.map((c) => { |
||||||
|
return ( |
||||||
|
<option key={c.id} value={c.id}> |
||||||
|
{c.nombreArchivo} |
||||||
|
</option> |
||||||
|
) |
||||||
|
}) |
||||||
|
: null} |
||||||
|
</Form.Control> |
||||||
|
</> |
||||||
|
) : ( |
||||||
|
<IconContext.Provider value={{ color: '#000000', size: '15px' }}> |
||||||
|
<BsX /> |
||||||
|
</IconContext.Provider> |
||||||
|
)} |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default CmbArchivos |
@ -0,0 +1,27 @@ |
|||||||
|
export default interface I2206EmbarquesMensual { |
||||||
|
id: number, |
||||||
|
patente: number, |
||||||
|
aduana: number, |
||||||
|
pedimento: string, |
||||||
|
partidas: number, |
||||||
|
tipoInsumo: string, |
||||||
|
fechaPedimento: string, |
||||||
|
fechaArribo: string, |
||||||
|
fechaEntrada: string, |
||||||
|
ordenCompra: string, |
||||||
|
factura: string, |
||||||
|
nombreProveedor: string, |
||||||
|
descripcionMaterial: string, |
||||||
|
valorAduanaMXP: string, |
||||||
|
montoAlmacenajes: number, |
||||||
|
fraccionArancelaria: string, |
||||||
|
incoterm: string, |
||||||
|
fletes: number, |
||||||
|
seguros: number, |
||||||
|
embalaje: number, |
||||||
|
otros: number, |
||||||
|
dta: number, |
||||||
|
igi: number, |
||||||
|
ieps: number, |
||||||
|
promedioDiasEnAduana: number
|
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
import { IServerSideTransactionManager } from "ag-grid-community"; |
||||||
|
import { ArrayDestructuringAssignment } from "typescript"; |
||||||
|
|
||||||
|
export default interface I2206EmbarquesPorImportar { |
||||||
|
id: number, |
||||||
|
aduana: string, |
||||||
|
destino: string, |
||||||
|
diasEnAduana: number, |
||||||
|
nombre: string, |
||||||
|
trafico: string, |
||||||
|
referencia: string, |
||||||
|
pedimento: string, |
||||||
|
clave:string, |
||||||
|
tipoOpercion: string, |
||||||
|
ordenCompra: string, |
||||||
|
factura: string, |
||||||
|
proveedor: string, |
||||||
|
descripcion: string, |
||||||
|
lineaTransportistaInternacional: string, |
||||||
|
lineaNaviera: string, |
||||||
|
mawb: string, |
||||||
|
hawb: string, |
||||||
|
fechaNotificacion: string, |
||||||
|
bultos: number, |
||||||
|
cantidadContenedores: number, |
||||||
|
pesoNeto: 0, |
||||||
|
incoterm: string, |
||||||
|
fechaETA: string, |
||||||
|
fechaEntrada: string, |
||||||
|
fechaRevalidacionGuia: string, |
||||||
|
montoUSA: number, |
||||||
|
origen: string, |
||||||
|
fraccionArancelaria: string, |
||||||
|
descripcionMercancia: string, |
||||||
|
preferenciaArancelaria: string, |
||||||
|
estatus: string, |
||||||
|
observaciones: string, |
||||||
|
fAlmacenajeInicioGastos: string, |
||||||
|
costoDiario: string, |
||||||
|
totalaPagar: number, |
||||||
|
fechaPago: string, |
||||||
|
fhInstrucciones: string, |
||||||
|
horaInstrucciones: string, |
||||||
|
fDespacho: string, |
||||||
|
diasCPPagado: number, |
||||||
|
fechaSalidaContenedores: string, |
||||||
|
nombrePaqueteriaInternacional: string, |
||||||
|
noGuia: string, |
||||||
|
fechaEntregaDestinoFinal: string |
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
export default interface I2206ExpedienteDigital { |
||||||
|
id: number, |
||||||
|
coincidencia: string, |
||||||
|
dato: string
|
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
export default interface I2206FacturasTxt { |
||||||
|
id: number |
||||||
|
delivery: string |
||||||
|
fecha: string |
||||||
|
factura: string |
||||||
|
poCliente: string |
||||||
|
heineken: string |
||||||
|
destino: string |
||||||
|
moneda: string |
||||||
|
numero4: number |
||||||
|
numero5: number |
||||||
|
numero6: number |
||||||
|
unidad: string |
||||||
|
numero7: number |
||||||
|
numero8: number |
||||||
|
incoterm: string |
||||||
|
incoterm2: string |
||||||
|
pedidoSAP: string |
||||||
|
transportista: string |
||||||
|
caja: string |
||||||
|
numero12: string |
||||||
|
fhCreacion: string |
||||||
|
activo: number |
||||||
|
max: boolean |
||||||
|
detail: Detail[] |
||||||
|
} |
||||||
|
|
||||||
|
interface Detail { |
||||||
|
id: number |
||||||
|
idHeader: number |
||||||
|
tipo: string |
||||||
|
seisDigitos: string |
||||||
|
veinteDigitos: string |
||||||
|
descripcion: string |
||||||
|
medida: string |
||||||
|
num1: number |
||||||
|
num2: number |
||||||
|
hNumero4: number |
||||||
|
num3: number |
||||||
|
hNumero6: number |
||||||
|
unidad: string |
||||||
|
hNumero7: number |
||||||
|
hNumero8: number |
||||||
|
fhCreacion: string |
||||||
|
activo: number |
||||||
|
} |
@ -0,0 +1,331 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import DataTable from 'react-data-table-component' |
||||||
|
import HeinekenDS from '../Services/Heineken.Services' |
||||||
|
import I2206EmbarquesPorImportar from '../Interfaces/I2206EmbarquesPorImportar' |
||||||
|
import CmbArchivos from '../Components/CmbArchivos' |
||||||
|
|
||||||
|
interface IProps {} |
||||||
|
|
||||||
|
export const RptEmbarquesImportar: FC<IProps> = (props) => { |
||||||
|
const [Data, setData] = useState<I2206EmbarquesPorImportar[]>([]) |
||||||
|
|
||||||
|
const colEmbarques = [ |
||||||
|
{ |
||||||
|
name: 'id', |
||||||
|
width: '80px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.id, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Aduana', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.aduana, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Destino', |
||||||
|
width: '200px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.destino, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Dias en aduana', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.diasEnAduana, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Nombre', |
||||||
|
width: '400px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.nombre, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Trafico', |
||||||
|
width: '100px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.trafico, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Referencia', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.referencia, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Pedimento', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.pedimento, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Clave', |
||||||
|
width: '80px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.clave, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Tipo operacion', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.tipoOpercion, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Orden compra', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.ordenCompra, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Factura', |
||||||
|
width: '100px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.factura, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Proveedor', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.proveedor, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Descripcion', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.descripcion, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Linea Transportista internacional', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.lineaTransportistaInternacional, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Linea Naviera', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.lineaNaviera, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'MAWB', |
||||||
|
width: '100px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.mawb, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'HAWB', |
||||||
|
width: '100px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.hawb, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fecha notificacion', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.fechaNotificacion, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Bultos', |
||||||
|
width: '100px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.bultos, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Cant. contenedores', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.cantidadContenedores, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Peso neto', |
||||||
|
width: '120px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.pesoNeto, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Incoterm', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.incoterm, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fecha ETA', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.fechaETA, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fecha entrada', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.fechaEntrada, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fecha revelidacion Guia', |
||||||
|
width: '250px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.fechaRevalidacionGuia, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Monto USA', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.montoUSA, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Origen', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.origen, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fraccion arancelaria', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.fraccionArancelaria, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Descripcion mercancia', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.descripcionMercancia, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Preferencia arancelaria', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.preferenciaArancelaria, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Estatus', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.estatus, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Observaciones', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.observaciones, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fecha almacenaje Inicio Gastos', |
||||||
|
width: '250px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.fAlmacenajeInicioGastos, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Costo diario', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.costoDiario, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Total a pagar', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.totalaPagar, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fecha pago', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.fechaPago, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fecha instrucciones', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.fhInstrucciones, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Hora instrucciones', |
||||||
|
width: '100px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.fhInstrucciones, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fecha despacho', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.fDespacho, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Dias CP Pagado', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.diasCPPagado, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fecha salida contenedores', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.fechaSalidaContenedores, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Nombre paqueteria internacional', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.nombrePaqueteriaInternacional, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'No Guia', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.noGuia, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fecha entrega destino final', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => row.fechaEntregaDestinoFinal, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Factura', |
||||||
|
width: '150px', |
||||||
|
cell: (row: I2206EmbarquesPorImportar) => { |
||||||
|
return <CmbArchivos id={row.id} docType={16} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Certificado de calidad', |
||||||
|
width: '200px', |
||||||
|
cell: (row: I2206EmbarquesPorImportar) => { |
||||||
|
return <CmbArchivos id={row.id} docType={15} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Packing list', |
||||||
|
width: '200px', |
||||||
|
cell: (row: I2206EmbarquesPorImportar) => { |
||||||
|
return <CmbArchivos id={row.id} docType={18} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Hoja Tecnica', |
||||||
|
width: '150px', |
||||||
|
cell: (row: I2206EmbarquesPorImportar) => { |
||||||
|
return <CmbArchivos id={row.id} docType={17} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'BL', |
||||||
|
width: '150px', |
||||||
|
cell: (row: I2206EmbarquesPorImportar) => { |
||||||
|
return <CmbArchivos id={row.id} docType={14} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Pedimento informativo', |
||||||
|
width: '200px', |
||||||
|
cell: (row: I2206EmbarquesPorImportar) => { |
||||||
|
return <CmbArchivos id={row.id} docType={12} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Pedimento simplificado', |
||||||
|
width: '200px', |
||||||
|
cell: (row: I2206EmbarquesPorImportar) => { |
||||||
|
return <CmbArchivos id={row.id} docType={13} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'DODA', |
||||||
|
width: '150px', |
||||||
|
cell: (row: I2206EmbarquesPorImportar) => { |
||||||
|
return <CmbArchivos id={row.id} docType={11} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Cuenta de Gastos', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesPorImportar) => '', |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
HeinekenDS.GetEmbarquesPorImportar() |
||||||
|
.then((response) => { |
||||||
|
setData(response.data) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
return |
||||||
|
}) |
||||||
|
}, []) |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<div className='MDcontainer'> |
||||||
|
<DataTable |
||||||
|
noHeader |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={colEmbarques} |
||||||
|
data={Data.filter(function (el) { |
||||||
|
return el.id > 0 |
||||||
|
})} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default RptEmbarquesImportar |
@ -0,0 +1,168 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import DataTable from 'react-data-table-component' |
||||||
|
import I2206EmbarquesMensual from '../Interfaces/I2206EmbarquesMensual' |
||||||
|
import I2206EmbarquesMenual from '../Interfaces/I2206EmbarquesMensual' |
||||||
|
import HeinekenDS from '../Services/Heineken.Services' |
||||||
|
|
||||||
|
interface IProps {} |
||||||
|
|
||||||
|
export const RptEmbarquesXMes: FC<IProps> = (props) => { |
||||||
|
const [Data, setData] = useState<I2206EmbarquesMensual[]>([]) |
||||||
|
|
||||||
|
const colEmbarques = [ |
||||||
|
{ |
||||||
|
name: 'id', |
||||||
|
width: '80px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.id, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Patente', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.patente, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Aduana', |
||||||
|
width: '200px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.aduana, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'No Pedimento', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.pedimento, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Partidas pedimento', |
||||||
|
width: '400px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.partidas, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Tipo insumo', |
||||||
|
width: '100px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.tipoInsumo, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fecha pedimento', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.fechaPedimento, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fecha arribo', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.fechaArribo, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fecha entrada', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.fechaEntrada, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Orden compra', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.ordenCompra, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Factura', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.factura, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Nombre proveedor', |
||||||
|
width: '250px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.nombreProveedor, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Descripcion material', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.descripcionMaterial, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Valor Aduana MXP', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.valorAduanaMXP, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Monto almacenajes', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.montoAlmacenajes, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fraccion arancelaria', |
||||||
|
width: '300px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.fraccionArancelaria, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Incoterm', |
||||||
|
width: '100px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.incoterm, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fletes', |
||||||
|
width: '100px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.fletes, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Seguros', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.seguros, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Embalaje', |
||||||
|
width: '100px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.embalaje, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Otros', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.otros, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'DTA', |
||||||
|
width: '120px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.dta, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'IGI', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.igi, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'IEPS', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.ieps, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Promedio dias en aduana', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206EmbarquesMensual) => row.promedioDiasEnAduana, |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
HeinekenDS.GetEmbarquesPorMes() |
||||||
|
.then((response) => { |
||||||
|
setData(response.data) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
return |
||||||
|
}) |
||||||
|
}, []) |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<div className='MDcontainer'> |
||||||
|
<DataTable |
||||||
|
noHeader |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={colEmbarques} |
||||||
|
data={Data.filter(function (el) { |
||||||
|
return el.id > 0 |
||||||
|
})} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,234 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import { Button, Col, Form, Modal, Row } from 'react-bootstrap' |
||||||
|
import DataTable from 'react-data-table-component' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import { BsFillCloudArrowDownFill } from 'react-icons/bs' |
||||||
|
import CmbArchivos from '../Components/CmbArchivos' |
||||||
|
import I2206ExpedienteDigital from '../Interfaces/I2206ExpedienteDigital' |
||||||
|
import HeinekenDS from '../Services/Heineken.Services' |
||||||
|
import loadingImg from '../../../../images/ajaxloader.gif' |
||||||
|
|
||||||
|
interface IProps {} |
||||||
|
|
||||||
|
/** |
||||||
|
* @author |
||||||
|
* @function @RptExpedienteDigital |
||||||
|
**/ |
||||||
|
|
||||||
|
export const RptExpedienteDigital: FC<IProps> = (props) => { |
||||||
|
const [Data, setData] = useState<I2206ExpedienteDigital[]>([]) |
||||||
|
const [Coincidencia, setCoincidencia] = useState('') |
||||||
|
const [showDialog, setShowDialog] = useState(false) |
||||||
|
|
||||||
|
const colEmbarques = [ |
||||||
|
{ |
||||||
|
name: 'id', |
||||||
|
width: '80px', |
||||||
|
selector: (row: I2206ExpedienteDigital) => row.id, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Coincidencia', |
||||||
|
width: '150px', |
||||||
|
selector: (row: I2206ExpedienteDigital) => row.coincidencia, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Dato', |
||||||
|
width: '200px', |
||||||
|
selector: (row: I2206ExpedienteDigital) => row.dato, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Factura', |
||||||
|
width: '150px', |
||||||
|
cell: (row: I2206ExpedienteDigital) => { |
||||||
|
return <CmbArchivos id={row.id} docType={16} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Certificado de calidad', |
||||||
|
width: '200px', |
||||||
|
cell: (row: I2206ExpedienteDigital) => { |
||||||
|
return <CmbArchivos id={row.id} docType={15} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Packing list', |
||||||
|
width: '200px', |
||||||
|
cell: (row: I2206ExpedienteDigital) => { |
||||||
|
return <CmbArchivos id={row.id} docType={18} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Hoja Tecnica', |
||||||
|
width: '150px', |
||||||
|
cell: (row: I2206ExpedienteDigital) => { |
||||||
|
return <CmbArchivos id={row.id} docType={17} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'BL', |
||||||
|
width: '150px', |
||||||
|
cell: (row: I2206ExpedienteDigital) => { |
||||||
|
return <CmbArchivos id={row.id} docType={14} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Pedimento informativo', |
||||||
|
width: '200px', |
||||||
|
cell: (row: I2206ExpedienteDigital) => { |
||||||
|
return <CmbArchivos id={row.id} docType={12} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Pedimento simplificado', |
||||||
|
width: '200px', |
||||||
|
cell: (row: I2206ExpedienteDigital) => { |
||||||
|
return <CmbArchivos id={row.id} docType={13} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'DODA', |
||||||
|
width: '150px', |
||||||
|
cell: (row: I2206ExpedienteDigital) => { |
||||||
|
return <CmbArchivos id={row.id} docType={11} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fotos', |
||||||
|
width: '150px', |
||||||
|
cell: (row: I2206ExpedienteDigital) => { |
||||||
|
return <CmbArchivos id={row.id} docType={10} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Todos', |
||||||
|
width: '150px', |
||||||
|
cell: (row: I2206ExpedienteDigital) => { |
||||||
|
return ( |
||||||
|
<IconContext.Provider value={{ color: '#4BFF59', size: '25px' }}> |
||||||
|
<BsFillCloudArrowDownFill |
||||||
|
onClick={() => { |
||||||
|
setShowDialog(true) |
||||||
|
downloadAllFiles(row.id) |
||||||
|
}} |
||||||
|
style={{ cursor: 'pointer' }} |
||||||
|
/> |
||||||
|
</IconContext.Provider> |
||||||
|
) |
||||||
|
}, |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
useEffect(() => {}, []) |
||||||
|
|
||||||
|
const loadReport = () => { |
||||||
|
HeinekenDS.GetExpedienteDigital(Coincidencia) |
||||||
|
.then((response) => { |
||||||
|
setData(response.data) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const downloadAllFiles = (id: number) => { |
||||||
|
HeinekenDS.GetAllFilesById(id) |
||||||
|
.then((response: any) => { |
||||||
|
if (response.status === 200) { |
||||||
|
let found = Data.filter((a) => { |
||||||
|
if (a.id == id) { |
||||||
|
return a |
||||||
|
} |
||||||
|
}) |
||||||
|
/* if (found[0].nombreArchivo.toLowerCase().endsWith('.pdf')) { |
||||||
|
// console.log(response.data)
|
||||||
|
const blob = new Blob([response.data], { type: 'application/pdf' }) |
||||||
|
const url = window.URL.createObjectURL(blob) |
||||||
|
window.open(url) |
||||||
|
} else if ( |
||||||
|
found[0].nombreArchivo.toLowerCase().endsWith('.png') || |
||||||
|
found[0].nombreArchivo.toLowerCase().endsWith('.jpg') |
||||||
|
) { |
||||||
|
const blob = new Blob([response.data], { type: 'image/png' }) |
||||||
|
const url = window.URL.createObjectURL(blob) |
||||||
|
window.open(url) |
||||||
|
} else { */ |
||||||
|
setShowDialog(false) |
||||||
|
const url = window.URL.createObjectURL(new Blob([response.data])) |
||||||
|
const link = document.createElement('a') |
||||||
|
link.href = url |
||||||
|
link.setAttribute('download', 'AllFiles.zip') |
||||||
|
document.body.appendChild(link) |
||||||
|
link.click() |
||||||
|
// }
|
||||||
|
} else { |
||||||
|
return |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Row style={{ paddingTop: '10px' }}> |
||||||
|
<Col xs={5}> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
id='Search' |
||||||
|
size='sm' |
||||||
|
placeholder='Criterio de busqueda...' |
||||||
|
value={Coincidencia} |
||||||
|
onChange={(e) => { |
||||||
|
setCoincidencia(e.target.value) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={2}> |
||||||
|
<Button |
||||||
|
variant='primary' |
||||||
|
size='sm' |
||||||
|
style={{ paddingLeft: '25px', paddingRight: '25px' }} |
||||||
|
onClick={() => loadReport()} |
||||||
|
> |
||||||
|
Buscar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={7}></Col> |
||||||
|
</Row> |
||||||
|
<div className='MDcontainer'> |
||||||
|
<DataTable |
||||||
|
noHeader |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={colEmbarques} |
||||||
|
data={Data.filter(function (el) { |
||||||
|
return el.id > 0 |
||||||
|
})} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
<Modal |
||||||
|
show={showDialog} |
||||||
|
onHide={() => { |
||||||
|
setShowDialog(false) |
||||||
|
}} |
||||||
|
backdrop='static' |
||||||
|
keyboard={false} |
||||||
|
size='sm' |
||||||
|
centered |
||||||
|
> |
||||||
|
<Modal.Header closeButton> |
||||||
|
<Modal.Title></Modal.Title> |
||||||
|
</Modal.Header> |
||||||
|
<Modal.Body> |
||||||
|
<img src={loadingImg} style={{ width: '50%', height: '50%' }} alt='proccessing' /> |
||||||
|
Espere, por favor... |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer></Modal.Footer> |
||||||
|
</Modal> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
import http from '../../../../Services/common/http-common'; |
||||||
|
import I2206EmbarquesMensual from '../Interfaces/I2206EmbarquesMensual'; |
||||||
|
import I2206EmbarquesPorImportar from '../Interfaces/I2206EmbarquesPorImportar'; |
||||||
|
import I2206ExpedienteDigital from '../Interfaces/I2206ExpedienteDigital'; |
||||||
|
import I2206FacturasTxt from '../Interfaces/I2206FacturasTxt'; |
||||||
|
|
||||||
|
class C1868HeinekenDataService { |
||||||
|
GetEmbarquesPorImportar() { |
||||||
|
return http.get<I2206EmbarquesPorImportar[]>(`/C2206Reportes/Rpt2206EmbarquesPorImportar`); |
||||||
|
} |
||||||
|
GetEmbarquesPorMes() { |
||||||
|
return http.get<I2206EmbarquesMensual[]>(`/C2206Reportes/Rpt2206EmbarquesPorMes`); |
||||||
|
} |
||||||
|
GetExpedienteDigital(Ocurrencia: string) { |
||||||
|
return http.get<I2206ExpedienteDigital[]>(`/C2206Reportes/Rpt2206ExpedienteDigital?Ocurrencia=${Ocurrencia}`); |
||||||
|
} |
||||||
|
GetAllFiles(id: number) { |
||||||
|
return http.get<I2206ExpedienteDigital[]>(`/C2206Reportes/Rpt2206ExpedienteDigital?Ocurrencia=${id}`); |
||||||
|
} |
||||||
|
GetAllFilesById(id: number) { |
||||||
|
return http.get<ArrayBuffer>(`/C2206Reportes/Get2206AllFiles?id=${id}`, {responseType: 'arraybuffer'}) |
||||||
|
.then(function (response) { |
||||||
|
return response |
||||||
|
}) |
||||||
|
.catch(function (error) { |
||||||
|
console.log(error) |
||||||
|
}) |
||||||
|
}
|
||||||
|
GetFacturasTxt() { |
||||||
|
return http.get<I2206FacturasTxt[]>(`/C2206Reportes/Rpt2206FacturasTxt`); |
||||||
|
}
|
||||||
|
} |
||||||
|
export default new C1868HeinekenDataService(); |
@ -0,0 +1,189 @@ |
|||||||
|
import React, { FC, useState } from 'react' |
||||||
|
import { Button, Col, Form, Row } from 'react-bootstrap' |
||||||
|
import DataTable from 'react-data-table-component' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import { BsEraserFill, BsFillPencilFill } from 'react-icons/bs' |
||||||
|
import { FaTimesCircle } from 'react-icons/fa' |
||||||
|
import { useDispatch, useSelector } from 'react-redux' |
||||||
|
import { updateCatDestinos } from '../../../../store/features/Clientes/1868/Cat1868DestinosSlice' |
||||||
|
import { RootState } from '../../../../store/store' |
||||||
|
import { MsgInformativo } from '../../../Utils/Toast/msgInformativo' |
||||||
|
import I1868CatDestinos from '../Interfaces/I1868CatDestinos' |
||||||
|
import FService from '../Services/Facturas.Services' |
||||||
|
|
||||||
|
interface IProps {} |
||||||
|
|
||||||
|
export const Cat1868Destinos: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch() |
||||||
|
const mCatDestinos = useSelector((state: RootState) => state.Cat1868Destinos.Cat1868Destinos) |
||||||
|
const [ID, setID] = useState(0) |
||||||
|
const [Lugar, setLugar] = useState('') |
||||||
|
const [Direccion, setDireccion] = useState('') |
||||||
|
const [Buscar, setBuscar] = useState('') |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [ShowModal, setShowModal] = useState(false) |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
const [msgColor, setMsgColor] = useState('primary') |
||||||
|
|
||||||
|
const colData = [ |
||||||
|
{ |
||||||
|
name: 'id', |
||||||
|
width: '6%', |
||||||
|
selector: (row: I1868CatDestinos) => row.id, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Lugar', |
||||||
|
width: '20%', |
||||||
|
selector: (row: I1868CatDestinos) => row.lugar, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Direccion', |
||||||
|
width: '60%', |
||||||
|
selector: (row: I1868CatDestinos) => row.direccion, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Edita', |
||||||
|
cell: (row: I1868CatDestinos) => ( |
||||||
|
<div |
||||||
|
style={{ textAlign: 'center', cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
setID(row.id) |
||||||
|
setLugar(row.lugar) |
||||||
|
setDireccion(row.direccion) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'blue', size: '25px' }}> |
||||||
|
<BsFillPencilFill /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
), |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
const deleteItem = (id: number) => { |
||||||
|
alert('Delete item ' + id) |
||||||
|
} |
||||||
|
|
||||||
|
const save = () => { |
||||||
|
const data: I1868CatDestinos = { |
||||||
|
id: ID, |
||||||
|
lugar: Lugar ? Lugar : '', |
||||||
|
direccion: Direccion ? Direccion : '', |
||||||
|
} |
||||||
|
FService.appendCatDestino(data) |
||||||
|
.then((response) => { |
||||||
|
setHeader('Confirmacion') |
||||||
|
setMsg('Los cambios se han guardado exitosamente.') |
||||||
|
dispatch(updateCatDestinos(response.data)) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const cleanForm = () => { |
||||||
|
setID(0) |
||||||
|
setLugar('') |
||||||
|
setDireccion('') |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Row> |
||||||
|
<Col xs={2}>Lugar</Col> |
||||||
|
<Col xs={4}> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
id='Lugar' |
||||||
|
value={Lugar} |
||||||
|
size='sm' |
||||||
|
onChange={(e) => { |
||||||
|
setLugar(e.target.value) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={2}> |
||||||
|
<Button |
||||||
|
variant='warning' |
||||||
|
size='sm' |
||||||
|
onClick={() => { |
||||||
|
cleanForm() |
||||||
|
}} |
||||||
|
> |
||||||
|
<BsEraserFill /> |
||||||
|
Limpiar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={2}></Col> |
||||||
|
<Col xs={1} style={{ textAlign: 'right' }}> |
||||||
|
<Button variant='primary' onClick={() => save()} size='sm'> |
||||||
|
Guardar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row style={{ paddingTop: '5px' }}> |
||||||
|
<Col xs={2}>Destino</Col> |
||||||
|
<Col xs={10}> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
id='Direccion' |
||||||
|
value={Direccion} |
||||||
|
size='sm' |
||||||
|
onChange={(e) => { |
||||||
|
setDireccion(e.target.value) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row style={{ paddingTop: '5px' }}> |
||||||
|
<Col xs={12}> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
id='Buscar' |
||||||
|
value={Buscar} |
||||||
|
placeholder='Search...' |
||||||
|
size='sm' |
||||||
|
onChange={(e) => { |
||||||
|
setBuscar(e.target.value) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row> |
||||||
|
<Col xs={12}> |
||||||
|
<DataTable |
||||||
|
noHeader |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={colData} |
||||||
|
data={mCatDestinos.filter(function (row) { |
||||||
|
return ( |
||||||
|
row.lugar.toLowerCase().includes(Buscar.toLowerCase()) || |
||||||
|
row.direccion.toLowerCase().includes(Buscar.toLowerCase()) |
||||||
|
) |
||||||
|
})} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
time={2000} |
||||||
|
msgColor={msgColor} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,162 @@ |
|||||||
|
import React, { FC, useState } from 'react' |
||||||
|
import { Button, Col, Form, Row } from 'react-bootstrap' |
||||||
|
import DataTable from 'react-data-table-component' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import { BsEraserFill, BsFillPencilFill } from 'react-icons/bs' |
||||||
|
import { useDispatch, useSelector } from 'react-redux' |
||||||
|
import { updateCatResponsables } from '../../../../store/features/Clientes/1868/Cat1868ResponsablesSlice' |
||||||
|
import { RootState } from '../../../../store/store' |
||||||
|
import { MsgInformativo } from '../../../Utils/Toast/msgInformativo' |
||||||
|
import I1868CatResponsables from '../Interfaces/I1868CatResponsables' |
||||||
|
import FService from '../Services/Facturas.Services' |
||||||
|
|
||||||
|
interface IProps {} |
||||||
|
|
||||||
|
export const Cat1868Responsables: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch() |
||||||
|
const mCatResponsables = useSelector((state: RootState) => state.Cat1868Responsables.Cat1868Responsables) |
||||||
|
const [ID, setID] = useState(0) |
||||||
|
const [Responsable, setResponsable] = useState('') |
||||||
|
const [Buscar, setBuscar] = useState('') |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [ShowModal, setShowModal] = useState(false) |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
const [msgColor, setMsgColor] = useState('primary') |
||||||
|
|
||||||
|
const colData = [ |
||||||
|
{ |
||||||
|
name: 'id', |
||||||
|
width: '10%', |
||||||
|
selector: (row: I1868CatResponsables) => row.id, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'responsable', |
||||||
|
width: '80%', |
||||||
|
selector: (row: I1868CatResponsables) => row.responsable, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Edita', |
||||||
|
cell: (row: I1868CatResponsables) => ( |
||||||
|
<div |
||||||
|
style={{ textAlign: 'center', cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
setID(row.id) |
||||||
|
setResponsable(row.responsable) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'blue', size: '25px' }}> |
||||||
|
<BsFillPencilFill /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
), |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
const deleteItem = (id: number) => { |
||||||
|
alert('Delete item ' + id) |
||||||
|
} |
||||||
|
|
||||||
|
const save = () => { |
||||||
|
const data: I1868CatResponsables = { |
||||||
|
id: ID, |
||||||
|
responsable: Responsable ? Responsable : '', |
||||||
|
} |
||||||
|
FService.appendCatResponsables(data) |
||||||
|
.then((response) => { |
||||||
|
setHeader('Confirmacion') |
||||||
|
setMsg('Los cambios se han guardado exitosamente.') |
||||||
|
dispatch(updateCatResponsables(response.data)) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const cleanForm = () => { |
||||||
|
setID(0) |
||||||
|
setResponsable('') |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Row> |
||||||
|
<Col xs={2}> |
||||||
|
<Button |
||||||
|
variant='warning' |
||||||
|
size='sm' |
||||||
|
onClick={() => { |
||||||
|
cleanForm() |
||||||
|
}} |
||||||
|
> |
||||||
|
<BsEraserFill /> |
||||||
|
Limpiar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={2}>Responsable </Col> |
||||||
|
<Col xs={6}> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
id='Responsable' |
||||||
|
value={Responsable} |
||||||
|
size='sm' |
||||||
|
onChange={(e) => { |
||||||
|
setResponsable(e.target.value) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
{/* <Col xs={0}></Col> */} |
||||||
|
<Col xs={1} style={{ textAlign: 'right' }}> |
||||||
|
<Button variant='primary' onClick={() => save()} size='sm'> |
||||||
|
Guardar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row style={{ paddingTop: '5px' }}> |
||||||
|
<Col xs={12}> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
id='Buscar' |
||||||
|
value={Buscar} |
||||||
|
placeholder='Search...' |
||||||
|
size='sm' |
||||||
|
onChange={(e) => { |
||||||
|
setBuscar(e.target.value) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row> |
||||||
|
<Col xs={12}> |
||||||
|
<DataTable |
||||||
|
noHeader |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={colData} |
||||||
|
data={mCatResponsables.filter(function (row) { |
||||||
|
return row.responsable.toLowerCase().includes(Buscar.toLowerCase()) |
||||||
|
})} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
time={2000} |
||||||
|
msgColor={msgColor} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,3 @@ |
|||||||
|
export default interface DTO1868Clientes { |
||||||
|
cliente: string
|
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
export default interface DTO1868Factura { |
||||||
|
id: number,
|
||||||
|
sello: string, |
||||||
|
placas: string, |
||||||
|
idResponsable: number, |
||||||
|
responsable: string, |
||||||
|
idDestino: number, |
||||||
|
entregar: string |
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
export default interface DTO1868FacturaDetalle { |
||||||
|
id: number, |
||||||
|
claveSAT : string, |
||||||
|
empaque: string
|
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
export default interface DTO1868ReporteFactura { |
||||||
|
id: number,
|
||||||
|
fechaFactura: string, |
||||||
|
invoice: string, |
||||||
|
pesoBruto: number, |
||||||
|
aduana: string, |
||||||
|
ruta: string, |
||||||
|
cliente: string, |
||||||
|
pedidoCliente: string, |
||||||
|
transportista: string, |
||||||
|
idResponsableCruce: number, |
||||||
|
responsableCruce: string, |
||||||
|
sello: string, |
||||||
|
placas: string, |
||||||
|
pallets: number,
|
||||||
|
carga: string, |
||||||
|
tipoPedimento: string, |
||||||
|
idDestino: number,
|
||||||
|
entregar: string, |
||||||
|
productoMateriaPrima: string, |
||||||
|
fraccionArancelaria: string, |
||||||
|
claveSAT1: string,
|
||||||
|
conceptoProductoMP: string, |
||||||
|
empaqueDescripcion: string, |
||||||
|
claveSAT2: string, |
||||||
|
conceptoEmbalaje: string, |
||||||
|
folioReferencia: string, |
||||||
|
idxml: number, |
||||||
|
idpdf: number, |
||||||
|
idDoda: number, |
||||||
|
idPrefile: number, |
||||||
|
scac: string, |
||||||
|
caat: string,
|
||||||
|
fRegistro: string, |
||||||
|
fActualizacion: string, |
||||||
|
activo: number |
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
export default interface DTO1868SCACCAAT { |
||||||
|
id: number, |
||||||
|
scac: string, |
||||||
|
caat: string |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
export default interface DTO1868Transportista { |
||||||
|
id: number,
|
||||||
|
responsableCruce: string, |
||||||
|
scac: string, |
||||||
|
caat: string, |
||||||
|
sello: string, |
||||||
|
placas: string, |
||||||
|
pallets: number,
|
||||||
|
pesoBruto: string, |
||||||
|
carga: string, |
||||||
|
tipoPedimento: string,
|
||||||
|
entregar: string, |
||||||
|
productoMateriaPrima: string, |
||||||
|
fraccionArancelaria: string, |
||||||
|
claveSAT1: string,
|
||||||
|
conceptoProductoMP: string, |
||||||
|
empaqueDescripcion: string, |
||||||
|
claveSAT2: string, |
||||||
|
conceptoEmbalaje: string, |
||||||
|
folioReferencia: string, |
||||||
|
aduana: string, |
||||||
|
idxml: number, |
||||||
|
idpdf: number,
|
||||||
|
fRegistro: string, |
||||||
|
fActualizacion: string, |
||||||
|
activo: number |
||||||
|
} |
@ -0,0 +1,3 @@ |
|||||||
|
export default interface DTORespuesta { |
||||||
|
respuesta: string |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
import React, { FC } from 'react' |
||||||
|
|
||||||
|
interface IProps {} |
||||||
|
|
||||||
|
export const Expandable: FC<IProps> = (props) => { |
||||||
|
return <div>ExpandableRowComponent</div> |
||||||
|
} |
||||||
|
|
||||||
|
export default Expandable |
@ -0,0 +1,6 @@ |
|||||||
|
export default interface I1868CatClaveSAT { |
||||||
|
id:number, |
||||||
|
clave: string, |
||||||
|
descripcion: string, |
||||||
|
activo: number |
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
export default interface I1868CatDestinos { |
||||||
|
id: number, |
||||||
|
lugar: string, |
||||||
|
direccion: string |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
export default interface I1868CatReponsables { |
||||||
|
id: number, |
||||||
|
responsable: string |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
export default interface I1868Factura { |
||||||
|
id: number,
|
||||||
|
fechaFactura: string, |
||||||
|
invoice: string, |
||||||
|
pesoBruto: number, |
||||||
|
aduana: string, |
||||||
|
ruta: string, |
||||||
|
cliente: string, |
||||||
|
pedidoCliente: string, |
||||||
|
transportista: string, |
||||||
|
responsableCruce: string, |
||||||
|
sello: string, |
||||||
|
placas: string, |
||||||
|
pallets: number,
|
||||||
|
carga: string, |
||||||
|
tipoPedimento: number,
|
||||||
|
productoMateriaPrima: string, |
||||||
|
fraccionArancelaria: string, |
||||||
|
claveSAT1: string,
|
||||||
|
conceptoProductoMP: string, |
||||||
|
empaqueDescripcion: string, |
||||||
|
claveSAT2: string, |
||||||
|
conceptoEmbalaje: string, |
||||||
|
folioReferencia: string, |
||||||
|
idpdf: number, |
||||||
|
fRegistro: string, |
||||||
|
fActualizacion: string, |
||||||
|
activo: number |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
import { number } from "yup" |
||||||
|
|
||||||
|
export default interface I1868FacturaDetalle { |
||||||
|
id: number, |
||||||
|
idFactura: number, |
||||||
|
partida: number, |
||||||
|
FFactura: string, |
||||||
|
pesoBruto: string, |
||||||
|
totalBultos: number, |
||||||
|
productoMateriaPrima: string, |
||||||
|
fraccionArancelaria: string, |
||||||
|
claveSAT1: string, |
||||||
|
conceptoProductoMP: string, |
||||||
|
empaqueDescripcion: string, |
||||||
|
claveSAT2: string, |
||||||
|
conceptoEmbalaje: string, |
||||||
|
minimizado: boolean, |
||||||
|
activo: string |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,257 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import { Alert, Button, Card, Col, Form, Modal, Row } from 'react-bootstrap' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import { BsFillPencilFill } from 'react-icons/bs' |
||||||
|
import { useDispatch, useSelector } from 'react-redux' |
||||||
|
import { RootState } from '../../../store/store' |
||||||
|
import { MsgInformativo } from '../../Utils/Toast/msgInformativo' |
||||||
|
import DTO1868FacturaDetalle from './DTO/DTO1868FacturaDetalle' |
||||||
|
import DTO1868ReporteFactura from './DTO/DTO1868ReporteFactura' |
||||||
|
import I1868CatClaveSAT from './Interfaces/I1868CatClaveSAT' |
||||||
|
import I1868FacturaDetalle from './Interfaces/I1868FacturaDetalle' |
||||||
|
import { updateFacturaDetalle, toggleRow } from '../../../store/features/Clientes/1868/Data1868FacturaDetalleSlice' |
||||||
|
import FService from './Services/Facturas.Services' |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
DataMaster: DTO1868ReporteFactura |
||||||
|
} |
||||||
|
|
||||||
|
export const Rpt1868FacturasDetalle: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch() |
||||||
|
const mDataFacturaDetalle = useSelector((state: RootState) => state.Data1868FacturaDetalle.Data1868FacturaDetalle) |
||||||
|
const mCatClaveSAT = useSelector((state: RootState) => state.Cat1868ClaveSAT.Cat1868ClaveSAT) |
||||||
|
const [UserType, setUserType] = useState(() => { |
||||||
|
const stickyValue = window.localStorage.getItem('UserType') |
||||||
|
return stickyValue !== null ? JSON.parse(stickyValue) : '' |
||||||
|
}) |
||||||
|
const [IDDetail, setIDDetail] = useState(0) |
||||||
|
const [ClaveSAT, setClaveSAT] = useState('-SELECCIONE-') |
||||||
|
const [Empaque, setEmpaque] = useState('') |
||||||
|
const [modalEditDetail, setModalEditDetail] = useState(false) |
||||||
|
const [DisplayTable, setDisplayTable] = useState(true) |
||||||
|
const [DataCatSAT, setDataCatSAT] = useState<I1868CatClaveSAT[]>([]) |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [ShowModal, setShowModal] = useState(false) |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
const [msgColor, setMsgColor] = useState('primary') |
||||||
|
|
||||||
|
const EditDetail = (f: DTO1868ReporteFactura, row: I1868FacturaDetalle) => { |
||||||
|
setIDDetail(row.id) |
||||||
|
const Clave = row.claveSAT2 |
||||||
|
setClaveSAT(Clave) |
||||||
|
var resultSAT = mCatClaveSAT.filter((row) => row.clave.includes(Clave)) |
||||||
|
setEmpaque(row.empaqueDescripcion) |
||||||
|
setModalEditDetail(true) |
||||||
|
} |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
mDataFacturaDetalle.forEach((onMemory) => { |
||||||
|
if (onMemory.idFactura === props.DataMaster.id) setDisplayTable(onMemory.minimizado) |
||||||
|
}) |
||||||
|
}, [mDataFacturaDetalle]) |
||||||
|
|
||||||
|
const saveDetail = () => { |
||||||
|
if (ClaveSAT === 'CLAVE SAT') { |
||||||
|
setModalEditDetail(false) |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Para poder guardar la informacion, seleccione la clave SAT correspondiente') |
||||||
|
setShowMsg(true) |
||||||
|
return false |
||||||
|
} |
||||||
|
const data: DTO1868FacturaDetalle = { |
||||||
|
id: IDDetail, |
||||||
|
claveSAT: ClaveSAT ? ClaveSAT : '', |
||||||
|
empaque: Empaque, |
||||||
|
} |
||||||
|
FService.UpdateDetail(data) |
||||||
|
.then((response) => { |
||||||
|
setHeader(response.data ? 'Informativo' : 'Error') |
||||||
|
setMsg( |
||||||
|
response.data ? 'La informacion se guardo correctamente' : 'Ocurrio un error, no se guardo la informacion' |
||||||
|
) |
||||||
|
dispatch(updateFacturaDetalle(response.data)) |
||||||
|
setModalEditDetail(false) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const changeClaveSAT = (value: string) => { |
||||||
|
setClaveSAT(value) |
||||||
|
var result = mCatClaveSAT.filter((row) => row.clave.includes(value)) |
||||||
|
setEmpaque(result[0] ? result[0].descripcion : '') |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<table className='zui-table zui-table-rounded' hidden={!DisplayTable}> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th style={{ width: '50px', textAlign: 'center' }}>Partida</th> |
||||||
|
<th style={{ width: '100px', textAlign: 'right' }}>Peso bruto</th> |
||||||
|
<th style={{ width: '100px', textAlign: 'right' }}>Pallets</th> |
||||||
|
<th style={{ width: '250px', textAlign: 'left' }}>Producto Materia Prima</th> |
||||||
|
<th style={{ width: '180px' }}>Fraccion Arancelaria</th> |
||||||
|
<th style={{ width: '100px' }}>Clave SAT</th> |
||||||
|
<th style={{ width: '250px' }}>Concepto Producto MP</th> |
||||||
|
<th style={{ width: '50px', textAlign: 'center' }}>Edita</th> |
||||||
|
<th style={{ width: '300px' }}>Empaque (descripcion)</th> |
||||||
|
<th style={{ width: '100px' }}>Clave SAT</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
{mDataFacturaDetalle |
||||||
|
? mDataFacturaDetalle.map((td) => { |
||||||
|
if (td.idFactura === props.DataMaster.id) |
||||||
|
return ( |
||||||
|
<tbody style={{ fontWeight: 'normal' }}> |
||||||
|
<tr style={{}}> |
||||||
|
<td |
||||||
|
style={{ |
||||||
|
fontWeight: 'bold', |
||||||
|
textAlign: 'center', |
||||||
|
backgroundColor: td.partida === 2 ? '#F0F7FC' : '#FFFFFF', |
||||||
|
}} |
||||||
|
> |
||||||
|
{td.partida} |
||||||
|
</td> |
||||||
|
<td |
||||||
|
style={{ |
||||||
|
textAlign: 'right', |
||||||
|
paddingRight: '10px', |
||||||
|
backgroundColor: td.partida === 2 ? '#F0F7FC' : '#FFFFFF', |
||||||
|
}} |
||||||
|
> |
||||||
|
{td.pesoBruto} |
||||||
|
</td> |
||||||
|
<td |
||||||
|
style={{ |
||||||
|
textAlign: 'right', |
||||||
|
paddingRight: '10px', |
||||||
|
backgroundColor: td.partida === 2 ? '#F0F7FC' : '#FFFFFF', |
||||||
|
}} |
||||||
|
> |
||||||
|
{td.totalBultos} |
||||||
|
</td> |
||||||
|
<td style={{ backgroundColor: td.partida === 2 ? '#F0F7FC' : '#FFFFFF' }}> |
||||||
|
{td.productoMateriaPrima} |
||||||
|
</td> |
||||||
|
<td style={{ backgroundColor: td.partida === 2 ? '#F0F7FC' : '#FFFFFF' }}> |
||||||
|
{td.fraccionArancelaria} |
||||||
|
</td> |
||||||
|
<td style={{ backgroundColor: td.partida === 2 ? '#F0F7FC' : '#FFFFFF' }}>{td.claveSAT1}</td> |
||||||
|
<td style={{ backgroundColor: td.partida === 2 ? '#F0F7FC' : '#FFFFFF' }}> |
||||||
|
{td.conceptoProductoMP} |
||||||
|
</td> |
||||||
|
<td style={{ backgroundColor: td.partida === 2 ? '#F0F7FC' : '#FFFFFF' }}> |
||||||
|
<Button |
||||||
|
size='sm' |
||||||
|
variant='light' |
||||||
|
style={{ |
||||||
|
textAlign: 'right', |
||||||
|
visibility: UserType === '4' || UserType === '2' ? 'visible' : 'hidden', |
||||||
|
}} |
||||||
|
onClick={() => { |
||||||
|
EditDetail(props.DataMaster, td) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'blue', size: '15px' }}> |
||||||
|
<BsFillPencilFill /> |
||||||
|
</IconContext.Provider> |
||||||
|
</Button> |
||||||
|
</td> |
||||||
|
<td style={{ backgroundColor: td.partida === 2 ? '#F0F7FC' : '#FFFFFF' }}> |
||||||
|
{td.empaqueDescripcion} |
||||||
|
</td> |
||||||
|
<td style={{ backgroundColor: td.partida === 2 ? '#F0F7FC' : '#FFFFFF' }}>{td.claveSAT2}</td> |
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
) |
||||||
|
}) |
||||||
|
: ''} |
||||||
|
</table> |
||||||
|
<Modal show={modalEditDetail} onHide={() => setModalEditDetail(false)} size='lg'> |
||||||
|
<Modal.Body> |
||||||
|
<Card className='labelSize13px'> |
||||||
|
<Card.Body> |
||||||
|
<Card> |
||||||
|
<Row> |
||||||
|
<Col xs={12}> |
||||||
|
<Alert variant='primary' style={{ textAlign: 'center' }}> |
||||||
|
<h6> |
||||||
|
Favor de proporcionar la siguiente informacion para complementar la factura [ |
||||||
|
{props.DataMaster.invoice}] |
||||||
|
<br /> |
||||||
|
</h6> |
||||||
|
</Alert> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row style={{ paddingTop: '10px', paddingBottom: '10px' }}> |
||||||
|
<Col xs={2}> |
||||||
|
<Form.Control |
||||||
|
as='select' |
||||||
|
value={ClaveSAT} |
||||||
|
onChange={(e) => { |
||||||
|
changeClaveSAT(e.target.value) |
||||||
|
}} |
||||||
|
className='form-select form-select-sm' |
||||||
|
> |
||||||
|
<option value='0'>CLAVE SAT</option> |
||||||
|
{mCatClaveSAT |
||||||
|
? mCatClaveSAT.map((a) => { |
||||||
|
return ( |
||||||
|
<option value={a.clave} key={a.id}> |
||||||
|
{a.clave} |
||||||
|
</option> |
||||||
|
) |
||||||
|
}) |
||||||
|
: null} |
||||||
|
</Form.Control> |
||||||
|
</Col> |
||||||
|
<Col xs={10}> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
id='Empaque' |
||||||
|
value={Empaque} |
||||||
|
disabled |
||||||
|
size='sm' |
||||||
|
onChange={(e) => { |
||||||
|
setEmpaque(e.target.value) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Card> |
||||||
|
</Card.Body> |
||||||
|
</Card> |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={10}> </Col> |
||||||
|
<Col xs={2}> |
||||||
|
<Button variant='primary' onClick={() => saveDetail()} size='sm'> |
||||||
|
Guardar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Footer> |
||||||
|
</Modal> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
time={2000} |
||||||
|
msgColor={msgColor} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,68 @@ |
|||||||
|
import http from '../../../../Services/common/http-common'; |
||||||
|
import DTO1868Clientes from '../DTO/DTO1868Clientes'; |
||||||
|
import DTO1868Factura from '../DTO/DTO1868Factura'; |
||||||
|
import DTO1868FacturaDetalle from '../DTO/DTO1868FacturaDetalle'; |
||||||
|
import DTO1868ReporteFactura from '../DTO/DTO1868ReporteFactura'; |
||||||
|
import DTO1868Transportista from '../DTO/DTO1868Transportista'; |
||||||
|
import DTO1868SCACCAAT from '../DTO/DTO1868SCACCAAT'; |
||||||
|
import DTORespuesta from '../DTO/DTORespuesta'; |
||||||
|
import I1868CatClaveSAT from '../Interfaces/I1868CatClaveSAT'; |
||||||
|
import I1868CatDestinos from '../Interfaces/I1868CatDestinos'; |
||||||
|
import I1868CatReponsables from '../Interfaces/I1868CatResponsables'; |
||||||
|
import I1868Factura from "../Interfaces/I1868Factura"; |
||||||
|
import I1868FacturaDetalle from '../Interfaces/I1868FacturaDetalle'; |
||||||
|
|
||||||
|
class C1868FacturasDataService { |
||||||
|
getAll(Inicio: string, Fin: string, UserId: number) { |
||||||
|
return http.get<DTO1868ReporteFactura[]>(`/Clientes/1868/C1868Factura/getAll?Inicio=${Inicio}&Fin=${Fin}&UserId=${UserId}`); |
||||||
|
} |
||||||
|
getAllDetail(Inicio: string, Fin: string) { |
||||||
|
return http.get<I1868FacturaDetalle[]>(`/Clientes/1868/C1868Factura/getAllDetail?Inicio=${Inicio}&Fin=${Fin}`); |
||||||
|
} |
||||||
|
getClientes() { |
||||||
|
return http.get<DTO1868Clientes[]>(`/Clientes/1868/C1868Factura/getClientes`); |
||||||
|
} |
||||||
|
getCatClaveSAT() { |
||||||
|
return http.get<I1868CatClaveSAT[]>(`/Clientes/1868/C1868Factura/getCatClaveSAT`); |
||||||
|
} |
||||||
|
getCatDestinos() { |
||||||
|
return http.get<I1868CatDestinos[]>(`/Clientes/1868/C1868Factura/getCatDestinos`); |
||||||
|
} |
||||||
|
getCatResponsables() { |
||||||
|
return http.get<I1868CatReponsables[]>(`/Clientes/1868/C1868Factura/getCatResponsables`); |
||||||
|
} |
||||||
|
appendCatDestino(data: I1868CatDestinos) { |
||||||
|
return http.post<I1868CatDestinos>(`/Clientes/1868/C1868Factura/appendCatDestinos`, data); |
||||||
|
} |
||||||
|
appendCatResponsables(data: I1868CatReponsables) { |
||||||
|
return http.post<I1868CatReponsables>(`/Clientes/1868/C1868Factura/appendCatResponsables`, data); |
||||||
|
} |
||||||
|
getRptTransportista(Inicio: string, Fin: string, UserId: number) { |
||||||
|
return http.get<DTO1868Transportista[]>(`/Clientes/1868/C1868Factura/getAll?Inicio=${Inicio}&Fin=${Fin}&UserId=${UserId}`); |
||||||
|
} |
||||||
|
Append(id: number, Proceso: number) { |
||||||
|
return http.post<I1868Factura[]>(`/Clientes/1868/C1868Factura/UploadFile?id=${id}&Proceso=${Proceso}`); |
||||||
|
} |
||||||
|
RelateByProcess(id: number, idFile: number, Proceso: number) { |
||||||
|
return http.post<I1868Factura[]>(`/Clientes/1868/C1868Factura/RelateByProcess?id=${id}&idFile=${idFile}&Proceso=${Proceso}`); |
||||||
|
} |
||||||
|
Update(data: DTO1868Factura) { |
||||||
|
return http.put<DTORespuesta>(`/Clientes/1868/C1868Factura/UpdateMaster/${data.id}`,data); |
||||||
|
} |
||||||
|
UpdateDetail(data: DTO1868FacturaDetalle) { |
||||||
|
return http.put<I1868FacturaDetalle>(`/Clientes/1868/C1868Factura/UpdateDetail/${data.id}`,data); |
||||||
|
} |
||||||
|
getFileContent(id: number, Proceso: number) { |
||||||
|
return http.get<ArrayBuffer>(`/Clientes/1868/C1868Factura/getFileContent?id=${id}`, {responseType: 'arraybuffer'}) |
||||||
|
.then(function (response) { |
||||||
|
return response |
||||||
|
}) |
||||||
|
.catch(function (error) { |
||||||
|
console.log(error) |
||||||
|
}) |
||||||
|
}
|
||||||
|
AppendSCACCAAT(data: DTO1868SCACCAAT) { |
||||||
|
return http.put<DTO1868SCACCAAT>(`/Clientes/1868/C1868Factura/AppendSCACCAAT/${data.id}`, data); |
||||||
|
} |
||||||
|
} |
||||||
|
export default new C1868FacturasDataService(); |
@ -0,0 +1,531 @@ |
|||||||
|
import { FC, useState } from 'react' |
||||||
|
import { Button, Card, Col, Form, Modal, Row } from 'react-bootstrap' |
||||||
|
import DataTable from 'react-data-table-component' |
||||||
|
import { BsFileEarmarkExcel, BsFilePdfFill, BsFillPencilFill, BsSearch } from 'react-icons/bs' |
||||||
|
import { MsgInformativo } from '../../../Utils/Toast/msgInformativo' |
||||||
|
import FService from '../Services/Facturas.Services' |
||||||
|
import * as XLSX from 'xlsx' |
||||||
|
import DTO1868Transportista from '../DTO/DTO1868Transportista' |
||||||
|
import FileManager from '../../../Utils/FileManager/FileManager' |
||||||
|
import FileManagerDS from '../../../../Services/Utils/FileManager.Services' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import DTO1868SCACCAAT from '../DTO/DTO1868SCACCAAT' |
||||||
|
|
||||||
|
interface IProps {} |
||||||
|
|
||||||
|
export const Rpt1868Transportista: FC<IProps> = (props) => { |
||||||
|
const [UserId, setUserId] = useState(() => { |
||||||
|
const stickyValue = window.localStorage.getItem('UserId') |
||||||
|
return stickyValue !== null ? JSON.parse(stickyValue) : 0 |
||||||
|
}) |
||||||
|
const [Depto, setDepto] = useState(() => { |
||||||
|
const stickyValue = window.localStorage.getItem('Departamento') |
||||||
|
return stickyValue !== null ? JSON.parse(stickyValue) : '' |
||||||
|
}) |
||||||
|
const [UserType, setUserType] = useState(() => { |
||||||
|
const stickyValue = window.localStorage.getItem('UserType') |
||||||
|
return stickyValue !== null ? JSON.parse(stickyValue) : '' |
||||||
|
}) |
||||||
|
const [Data, setData] = useState<DTO1868Transportista[]>([]) |
||||||
|
const [DataOriginal, setDataOriginal] = useState<DTO1868Transportista[]>([]) |
||||||
|
const [ID, setID] = useState(0) |
||||||
|
const [Process, setProcess] = useState(9) |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
const [Inicio, setInicio] = useState(currentDate(-30)) |
||||||
|
const [Fin, setFin] = useState(currentDate(0)) |
||||||
|
const [modalFileManagerPDF, setModalFileManagerPDF] = useState(false) |
||||||
|
const [ModalData, setModalData] = useState(false) |
||||||
|
const [filtro, setFiltro] = useState('') |
||||||
|
const [SCAC, setSCAC] = useState('') |
||||||
|
const [CAAT, setCAAT] = useState('') |
||||||
|
const [msgColor, setMsgColor] = useState('primary') |
||||||
|
const columnsConcepts = [ |
||||||
|
{ |
||||||
|
name: 'PDF', |
||||||
|
width: '55px', |
||||||
|
cell: (row: DTO1868Transportista) => ( |
||||||
|
<div |
||||||
|
style={{ textAlign: 'center', cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
choosePDF(row) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'red', size: '25px' }}> |
||||||
|
<BsFilePdfFill /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
), |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'SCAC', |
||||||
|
width: '100px', |
||||||
|
selector: (row: DTO1868Transportista) => row.scac, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'CAAT', |
||||||
|
width: '100px', |
||||||
|
selector: (row: DTO1868Transportista) => row.caat, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: '', |
||||||
|
width: '55px', |
||||||
|
cell: (row: DTO1868Transportista) => ( |
||||||
|
<div |
||||||
|
style={{ textAlign: 'center', cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
setID(row.id) |
||||||
|
setModalData(true) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'blue', size: '15px' }}> |
||||||
|
<BsFillPencilFill /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
), |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Responsable cruce', |
||||||
|
width: '250px', |
||||||
|
selector: (row: DTO1868Transportista) => row.responsableCruce, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Sello', |
||||||
|
width: '100px', |
||||||
|
selector: (row: DTO1868Transportista) => (row.sello ? row.sello : ''), |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Placas', |
||||||
|
width: '190px', |
||||||
|
selector: (row: DTO1868Transportista) => row.placas, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Pallets', |
||||||
|
width: '100px', |
||||||
|
selector: (row: DTO1868Transportista) => row.pallets, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Peso Bruto', |
||||||
|
width: '150px', |
||||||
|
selector: (row: DTO1868Transportista) => row.pesoBruto.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','), |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Carga', |
||||||
|
width: '100px', |
||||||
|
selector: (row: DTO1868Transportista) => row.carga, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Tipo pedimento', |
||||||
|
width: '135px', |
||||||
|
selector: (row: DTO1868Transportista) => row.tipoPedimento, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Entregar en', |
||||||
|
width: '850px', |
||||||
|
selector: (row: DTO1868Transportista) => row.entregar, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Aduana', |
||||||
|
width: '150px', |
||||||
|
selector: (row: DTO1868Transportista) => row.aduana, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Producto/Materia prima', |
||||||
|
width: '350px', |
||||||
|
selector: (row: DTO1868Transportista) => row.productoMateriaPrima, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Fraccion arancelaria', |
||||||
|
width: '150px', |
||||||
|
selector: (row: DTO1868Transportista) => row.fraccionArancelaria, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Clave SAT', |
||||||
|
width: '150px', |
||||||
|
selector: (row: DTO1868Transportista) => row.claveSAT1, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Concepto Producto / MP', |
||||||
|
width: '250px', |
||||||
|
selector: (row: DTO1868Transportista) => row.conceptoProductoMP, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Empaque (descripcion)', |
||||||
|
width: '550px', |
||||||
|
selector: (row: DTO1868Transportista) => row.empaqueDescripcion, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Clave SAT', |
||||||
|
width: '120px', |
||||||
|
selector: (row: DTO1868Transportista) => row.claveSAT2, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
const choosePDF = (row: DTO1868Transportista) => { |
||||||
|
setID(row.id) |
||||||
|
FileManagerDS.getFileContent(row.id, Process) |
||||||
|
.then((response: any) => { |
||||||
|
if (response.status === 200) { |
||||||
|
console.log(response.data) |
||||||
|
const blob = new Blob([response.data], { type: 'application/pdf' }) |
||||||
|
const url = window.URL.createObjectURL(blob) |
||||||
|
window.open(url) |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setModalFileManagerPDF(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
function exportExcel(jsonData: DTO1868Transportista[], fileName: string): void { |
||||||
|
let Heading = [ |
||||||
|
[ |
||||||
|
'Responsable cruce', |
||||||
|
'Sellos', |
||||||
|
'Placas', |
||||||
|
'Pallets', |
||||||
|
'Peso bruto', |
||||||
|
'Carga', |
||||||
|
'Tipo pedimento', |
||||||
|
'Entregar en', |
||||||
|
'Aduana', |
||||||
|
'Producto materia prima', |
||||||
|
'Fraccion arancelaria', |
||||||
|
'Clave SAT', |
||||||
|
'Concepto producto MP', |
||||||
|
'Empaque descripcion', |
||||||
|
'Clave SAT', |
||||||
|
], |
||||||
|
] |
||||||
|
const dataOnly = jsonData.map( |
||||||
|
({ |
||||||
|
responsableCruce, |
||||||
|
sello, |
||||||
|
placas, |
||||||
|
pallets, |
||||||
|
pesoBruto, |
||||||
|
carga, |
||||||
|
tipoPedimento, |
||||||
|
entregar, |
||||||
|
aduana, |
||||||
|
productoMateriaPrima, |
||||||
|
fraccionArancelaria, |
||||||
|
claveSAT1, |
||||||
|
conceptoProductoMP, |
||||||
|
empaqueDescripcion, |
||||||
|
claveSAT2, |
||||||
|
}) => { |
||||||
|
return { |
||||||
|
responsableCruce, |
||||||
|
sello, |
||||||
|
placas, |
||||||
|
pallets, |
||||||
|
pesoBruto, |
||||||
|
carga, |
||||||
|
tipoPedimento, |
||||||
|
entregar, |
||||||
|
aduana, |
||||||
|
productoMateriaPrima, |
||||||
|
fraccionArancelaria, |
||||||
|
claveSAT1, |
||||||
|
conceptoProductoMP, |
||||||
|
empaqueDescripcion, |
||||||
|
claveSAT2, |
||||||
|
} |
||||||
|
} |
||||||
|
) |
||||||
|
const wb = XLSX.utils.book_new() |
||||||
|
const ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet([]) |
||||||
|
XLSX.utils.sheet_add_aoa(ws, Heading) |
||||||
|
XLSX.utils.sheet_add_json(ws, dataOnly, { origin: 'A2', skipHeader: true }) |
||||||
|
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1') |
||||||
|
XLSX.writeFile(wb, fileName + '.xlsx') |
||||||
|
var range = XLSX.utils.decode_range(ws['!ref?']) |
||||||
|
for (var C = range.s.c + 1; C <= range.e.c + 1; ++C) { |
||||||
|
var address = XLSX.utils.encode_col(C) + '1' // <-- first row, column number C
|
||||||
|
if (!ws[address]) continue |
||||||
|
ws[address].v = ws[address].v.toUpperCase() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function currentDate(days: number): string { |
||||||
|
var today = new Date() |
||||||
|
today.setDate(today.getDate() + days) |
||||||
|
var dd = String(today.getDate()).padStart(2, '0') |
||||||
|
var mm = String(today.getMonth() + 1).padStart(2, '0') |
||||||
|
var yyyy = today.getFullYear() |
||||||
|
return yyyy + '-' + mm + '-' + dd |
||||||
|
} |
||||||
|
|
||||||
|
const generaReporte = () => { |
||||||
|
FService.getRptTransportista(Inicio, Fin, UserId) |
||||||
|
.then((response) => { |
||||||
|
setData(response.data) |
||||||
|
setDataOriginal(response.data) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const filtraReporte = (e: any) => { |
||||||
|
let value = e.target.value |
||||||
|
value = value.toUpperCase() |
||||||
|
setFiltro(value) |
||||||
|
if (value.length > 0) { |
||||||
|
console.log(value) |
||||||
|
setData( |
||||||
|
Data.filter(function (row: DTO1868Transportista) { |
||||||
|
return ( |
||||||
|
row.responsableCruce.includes(value) || |
||||||
|
row.pallets.toString().includes(value) || |
||||||
|
row.pesoBruto.toString().includes(value) || |
||||||
|
row.carga.includes(value) || |
||||||
|
row.tipoPedimento.includes(value) || |
||||||
|
row.aduana.includes(value) || |
||||||
|
row.fraccionArancelaria.includes(value) |
||||||
|
) |
||||||
|
}) |
||||||
|
) |
||||||
|
console.log(Data) |
||||||
|
} else { |
||||||
|
setData(DataOriginal) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const downloadExcel = () => { |
||||||
|
exportExcel(Data, 'Reporte de Facturas de Zinc Internacional') |
||||||
|
} |
||||||
|
|
||||||
|
const uploadPDF = (idFile: number, Process: number) => { |
||||||
|
FService.Append(idFile, Process) |
||||||
|
.then((response) => { |
||||||
|
if (!response.data) { |
||||||
|
console.log('Ocurrio un error, esto es lo que regreso del backend: ' + response.data) |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error, no se guardo correctamente el archivo') |
||||||
|
setShowMsg(true) |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const saveSCACCAAT = () => { |
||||||
|
const data: DTO1868SCACCAAT = { |
||||||
|
id: ID, |
||||||
|
scac: SCAC, |
||||||
|
caat: CAAT, |
||||||
|
} |
||||||
|
FService.AppendSCACCAAT(data) |
||||||
|
.then((response) => { |
||||||
|
generaReporte() |
||||||
|
setHeader('Informativo') |
||||||
|
setMsg('La informacion se guardo existosamente') |
||||||
|
setModalData(false) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setModalData(false) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Card> |
||||||
|
<Card.Body> |
||||||
|
<div className='row'> |
||||||
|
<div className='col-md-1'> |
||||||
|
<Form.Control |
||||||
|
defaultValue={Inicio} |
||||||
|
type='date' |
||||||
|
name='Inicio' |
||||||
|
placeholder='Inicio' |
||||||
|
title='Inicio' |
||||||
|
alt='Inicio' |
||||||
|
data-date-format='YYYY-mm-dd' |
||||||
|
onChange={(e) => setInicio(e.target.value)} |
||||||
|
size='sm' |
||||||
|
/> |
||||||
|
</div> |
||||||
|
<div className='col-md-1'> |
||||||
|
<Form.Control |
||||||
|
defaultValue={Fin} |
||||||
|
type='date' |
||||||
|
name='Fin' |
||||||
|
placeholder='Fin' |
||||||
|
title='Fin' |
||||||
|
alt='Fin' |
||||||
|
onChange={(e) => setFin(e.target.value)} |
||||||
|
size='sm' |
||||||
|
/> |
||||||
|
</div> |
||||||
|
<div className='col-md-1'></div> |
||||||
|
<div className='col-md-2'></div> |
||||||
|
<div className='col-md-3'> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
size='sm' |
||||||
|
placeholder='Search...' |
||||||
|
onChange={(e) => { |
||||||
|
filtraReporte(e) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
<div className='col-md-1 right-label'> |
||||||
|
<Button |
||||||
|
variant='primary' |
||||||
|
size='sm' |
||||||
|
onClick={() => { |
||||||
|
generaReporte() |
||||||
|
}} |
||||||
|
> |
||||||
|
<BsSearch /> |
||||||
|
Buscar |
||||||
|
</Button> |
||||||
|
</div> |
||||||
|
<div className='col'> |
||||||
|
<Button |
||||||
|
size='sm' |
||||||
|
variant='success' |
||||||
|
onClick={() => { |
||||||
|
downloadExcel() |
||||||
|
}} |
||||||
|
> |
||||||
|
<BsFileEarmarkExcel /> |
||||||
|
Descarga |
||||||
|
</Button> |
||||||
|
</div> |
||||||
|
<div className='col'></div> |
||||||
|
</div> |
||||||
|
</Card.Body> |
||||||
|
</Card> |
||||||
|
<br /> |
||||||
|
<div className='ag-theme-alpine' style={{ height: 500, width: '100%' }}> |
||||||
|
{ |
||||||
|
<DataTable |
||||||
|
noHeader |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
striped={true} |
||||||
|
dense={true} |
||||||
|
paginationPerPage={10} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={columnsConcepts} |
||||||
|
data={Data} |
||||||
|
pointerOnHover |
||||||
|
/> |
||||||
|
} |
||||||
|
</div> |
||||||
|
<Modal show={modalFileManagerPDF} onHide={() => setModalFileManagerPDF(false)} size='lg'> |
||||||
|
<Modal.Body> |
||||||
|
<FileManager |
||||||
|
width={750} |
||||||
|
height={200} |
||||||
|
IDProcess={Process} |
||||||
|
IdFile={ID} |
||||||
|
IDUser={UserId} |
||||||
|
FileName={''} |
||||||
|
canDelete={false} |
||||||
|
FileType={['pdf']} |
||||||
|
Leyenda={ |
||||||
|
'Estimado colaborador, favor de seleccionar el archivo PDF, arrastrelo hasta aqui y sueltelo para agregar la informacion a este reporte...' |
||||||
|
} |
||||||
|
onAppendFM={function (idFile: number): void { |
||||||
|
uploadPDF(idFile, Process) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={11}> </Col> |
||||||
|
<Col xs={1}> |
||||||
|
<Button variant='secondary' onClick={() => setModalFileManagerPDF(false)} size='sm'> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Footer> |
||||||
|
</Modal> |
||||||
|
<Modal show={ModalData} onHide={() => setModalData(false)} size='lg'> |
||||||
|
<Row style={{ paddingTop: '20px', paddingBottom: '20px' }}> |
||||||
|
<Col xs={2} style={{ textAlign: 'right' }}> |
||||||
|
<Button variant='secondary' onClick={() => setModalData(false)} size='sm'> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={1}>{ID}</Col> |
||||||
|
<Col xs={1}>SCAC</Col> |
||||||
|
<Col xs={2}> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
id='SCAC' |
||||||
|
value={SCAC} |
||||||
|
size='sm' |
||||||
|
onChange={(e) => { |
||||||
|
setSCAC(e.target.value) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={1}>CAAT</Col> |
||||||
|
<Col xs={2}> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
id='CAAT' |
||||||
|
value={CAAT} |
||||||
|
size='sm' |
||||||
|
onChange={(e) => { |
||||||
|
setCAAT(e.target.value) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={1}></Col> |
||||||
|
<Col xs={2}> |
||||||
|
<Button variant='primary' onClick={() => saveSCACCAAT()} size='sm'> |
||||||
|
Guardar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
time={2000} |
||||||
|
msgColor={msgColor} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,614 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import { Alert, Button, Col, Container, Form, Modal, Row } from 'react-bootstrap' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import { |
||||||
|
BsCash, |
||||||
|
BsCheckCircle, |
||||||
|
BsCheckCircleFill, |
||||||
|
BsEraserFill, |
||||||
|
BsFileEarmarkPdf, |
||||||
|
BsFillXCircleFill, |
||||||
|
BsPencilFill, |
||||||
|
BsQuestionOctagonFill, |
||||||
|
} from 'react-icons/bs' |
||||||
|
import { MsgInformativo } from '../../Utils/Toast/msgInformativo' |
||||||
|
import 'react-flexy-table/dist/index.css' |
||||||
|
import DTOItems from '../../../DTO/Corresponsales/DTOItems' |
||||||
|
import CAnticiposDataService from '../../../Services/Corresponsalias/Corresponsales.Anticipos.Services' |
||||||
|
|
||||||
|
import { |
||||||
|
populateCorresponsalesAnticipos, |
||||||
|
addCorresponsalesAnticipos, |
||||||
|
deleteCorresponsalesAnticipos, |
||||||
|
updateCorresponsalesAnticipos, |
||||||
|
} from '../../../store/features/Corresponsales/CorresponsalesAnticiposSlice' |
||||||
|
import ICorresponsalAnticipos from '../../../Interfaces/Corresponsales/ICorresponsalAnticipos' |
||||||
|
import { useDispatch, useSelector } from 'react-redux' |
||||||
|
import { RootState } from '../../../store/store' |
||||||
|
import { AgGridReact } from 'ag-grid-react' |
||||||
|
import { RowClickedEvent } from 'ag-grid-community' |
||||||
|
import { BiCoinStack } from 'react-icons/bi' |
||||||
|
import * as CurrencyFormat from 'react-currency-format' |
||||||
|
import FileManager from '../../Utils/FileManager/FileManager' |
||||||
|
import DTOAnticiposAutoriza from '../../../DTO/Corresponsales/DTOAnticiposAutoriza' |
||||||
|
|
||||||
|
interface ItemList { |
||||||
|
id: number |
||||||
|
item: string |
||||||
|
} |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
IDTrafico: number |
||||||
|
closeCRUDItems: (arg: boolean) => void |
||||||
|
canDelete: boolean |
||||||
|
} |
||||||
|
|
||||||
|
export const Anticipos: FC<IProps> = (props) => { |
||||||
|
const [UserId, setUserId] = useState(() => { |
||||||
|
const stickyValue = window.localStorage.getItem('UserId') |
||||||
|
return stickyValue !== null ? JSON.parse(stickyValue) : 0 |
||||||
|
}) |
||||||
|
const [Depto, setDept] = useState(() => { |
||||||
|
const Depto = window.localStorage.getItem('Departamento') |
||||||
|
return Depto !== null ? JSON.parse(Depto) : '' |
||||||
|
}) |
||||||
|
const mCAnticipos = useSelector((state: RootState) => state.CAnticipos.CorresponsalesAnticipos) |
||||||
|
const [allItems, setAllItems] = useState<DTOItems[]>([]) |
||||||
|
const [filteredData, setFilteredData] = useState<ICorresponsalAnticipos[]>([]) |
||||||
|
const [IdAnticipo, setIdAnticipo] = useState(0) |
||||||
|
const [Anticipo, setAnticipo] = useState(0) |
||||||
|
const [Moneda, setMoneda] = useState(2) |
||||||
|
const [Financiado, setFinanciado] = useState(0) |
||||||
|
const [Concepto, setConcepto] = useState('') |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msgColor, setMsgColor] = React.useState('primary') |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
const [msgDialog, setMsgDialog] = useState(false) |
||||||
|
const [MsgDialogFileManager, setMsgDialogFileManager] = useState(false) |
||||||
|
const [msgDialogFileManagerConta, setMsgDialogFileManagerConta] = useState(false) |
||||||
|
const gridRef = React.useRef<any>(null) |
||||||
|
const [deleteFile, setDeleteFile] = useState(false) |
||||||
|
const [columnDefs] = useState([ |
||||||
|
Depto === 'Corresponsalias' |
||||||
|
? { |
||||||
|
field: 'id', |
||||||
|
headerName: 'Acciones', |
||||||
|
width: 110, |
||||||
|
sortable: true, |
||||||
|
filter: true, |
||||||
|
cellRenderer: (params: any) => { |
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<IconContext.Provider value={{ color: 'blue', size: '18px' }}> |
||||||
|
<BsPencilFill |
||||||
|
onClick={() => { |
||||||
|
loadRow(params.data.id) |
||||||
|
}} |
||||||
|
style={{ cursor: 'pointer' }} |
||||||
|
/> |
||||||
|
</IconContext.Provider> |
||||||
|
|
||||||
|
<IconContext.Provider value={{ color: 'red', size: '20px' }}> |
||||||
|
<BsFileEarmarkPdf |
||||||
|
onClick={() => { |
||||||
|
viewDoc(params.value) |
||||||
|
//getFileContent(params.value)
|
||||||
|
}} |
||||||
|
style={{ cursor: 'pointer' }} |
||||||
|
/> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
) |
||||||
|
}, |
||||||
|
} |
||||||
|
: { |
||||||
|
field: 'id', |
||||||
|
headerName: 'id', |
||||||
|
width: 60, |
||||||
|
sortable: false, |
||||||
|
filter: false, |
||||||
|
visible: false, |
||||||
|
}, |
||||||
|
{ |
||||||
|
field: 'anticipo', |
||||||
|
headerName: 'Anticipo', |
||||||
|
width: 120, |
||||||
|
sortable: true, |
||||||
|
filter: true, |
||||||
|
cellRenderer: (params: any) => { |
||||||
|
return ( |
||||||
|
<CurrencyFormat |
||||||
|
value={params.value} |
||||||
|
displayType={'text'} |
||||||
|
thousandSeparator={true} |
||||||
|
prefix={'$'} |
||||||
|
decimalScale={2} |
||||||
|
fixedDecimalScale={true} |
||||||
|
/> |
||||||
|
) |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
field: 'moneda', |
||||||
|
headerName: 'Moneda', |
||||||
|
width: 105, |
||||||
|
sortable: true, |
||||||
|
filter: true, |
||||||
|
cellRenderer: (params: any) => { |
||||||
|
if (params.value === 1) { |
||||||
|
return ( |
||||||
|
<IconContext.Provider value={{ color: '#E5E041', size: '18px' }}> |
||||||
|
<BiCoinStack /> Pesos |
||||||
|
</IconContext.Provider> |
||||||
|
) |
||||||
|
} else if (params.value === 2) { |
||||||
|
return ( |
||||||
|
<IconContext.Provider value={{ color: 'green', size: '18px' }}> |
||||||
|
<BsCash /> Dollar |
||||||
|
</IconContext.Provider> |
||||||
|
) |
||||||
|
} else return '?' |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
field: 'financiado', |
||||||
|
headerName: '¿Financiado?', |
||||||
|
width: 135, |
||||||
|
sortable: true, |
||||||
|
filter: true, |
||||||
|
cellRenderer: (params: any) => { |
||||||
|
if (params.value === 1) |
||||||
|
return ( |
||||||
|
<div style={{ paddingLeft: '30px' }}> |
||||||
|
<IconContext.Provider value={{ color: 'green', size: '20px' }}> |
||||||
|
<BsCheckCircleFill /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
) |
||||||
|
else |
||||||
|
return ( |
||||||
|
<div style={{ paddingLeft: '30px' }}> |
||||||
|
<IconContext.Provider value={{ color: 'red', size: '20px' }}> |
||||||
|
<BsFillXCircleFill /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
) |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
field: 'id', |
||||||
|
headerName: 'Autorizado', |
||||||
|
width: 130, |
||||||
|
sortable: true, |
||||||
|
filter: true, |
||||||
|
cellRenderer: (params: any) => { |
||||||
|
if (params.data.autoriza === 0) |
||||||
|
return ( |
||||||
|
<div style={{ paddingLeft: '30px' }}> |
||||||
|
<IconContext.Provider value={{ color: 'red', size: '18px' }}> |
||||||
|
<BsQuestionOctagonFill |
||||||
|
onClick={() => { |
||||||
|
return Depto === 'Contabilidad' ? viewDocConta(params.value) : '#' |
||||||
|
}} |
||||||
|
style={{ cursor: 'pointer' }} |
||||||
|
/> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
) |
||||||
|
else |
||||||
|
return ( |
||||||
|
<div style={{ paddingLeft: '30px' }}> |
||||||
|
<IconContext.Provider value={{ color: 'green', size: '18px' }}> |
||||||
|
<BsCheckCircleFill |
||||||
|
onClick={() => { |
||||||
|
viewDocConta(params.value) |
||||||
|
}} |
||||||
|
style={{ cursor: 'pointer' }} |
||||||
|
/> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
) |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ field: 'concepto', headerName: 'Concepto', width: 350, sortable: true, filter: true }, |
||||||
|
{ field: 'sSolicita', headerName: 'Solicita', width: 150, sortable: true, filter: true }, |
||||||
|
{ |
||||||
|
field: 'fhSolicita', |
||||||
|
headerName: 'Fecha solicitud', |
||||||
|
width: 200, |
||||||
|
sortable: true, |
||||||
|
filter: true, |
||||||
|
cellRenderer: (params: any) => { |
||||||
|
if (params.value !== null) { |
||||||
|
return params.value.substring(0, 16) |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ field: 'sAutoriza', headerName: 'Authoriza', width: 150, sortable: true, filter: true }, |
||||||
|
{ field: 'fhAutoriza', headerName: 'Fecha autorizacion', width: 200, sortable: true, filter: true }, |
||||||
|
]) |
||||||
|
const dispatch = useDispatch() |
||||||
|
|
||||||
|
const cleanForm = () => { |
||||||
|
setIdAnticipo(0) |
||||||
|
setAnticipo(0) |
||||||
|
setMoneda(2) |
||||||
|
setConcepto('') |
||||||
|
} |
||||||
|
|
||||||
|
const saveForm = () => { |
||||||
|
if (Concepto.length < 5) { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Para poder guardar la informacion, proporcione el concepto') |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
} |
||||||
|
if (Anticipo === 0) { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Para poder guardar la informacion, proporcione el monto del anticipo') |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
} |
||||||
|
const data: ICorresponsalAnticipos = { |
||||||
|
id: IdAnticipo, |
||||||
|
idTrafico: props.IDTrafico, |
||||||
|
anticipo: Anticipo, |
||||||
|
moneda: Moneda, |
||||||
|
concepto: Concepto, |
||||||
|
solicita: UserId, |
||||||
|
fhSolicita: '', |
||||||
|
financiado: Financiado, |
||||||
|
} |
||||||
|
CAnticiposDataService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
setHeader('Informativo') |
||||||
|
setMsg('La informcion se guardo correctamente') |
||||||
|
setShowMsg(true) |
||||||
|
if (IdAnticipo === 0) dispatch(addCorresponsalesAnticipos(response.data)) |
||||||
|
else dispatch(updateCorresponsalesAnticipos(response.data)) |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const loadRow = (idRow: number) => { |
||||||
|
var tmpArray = mCAnticipos.filter(function (item) { |
||||||
|
return item.id === idRow |
||||||
|
}) |
||||||
|
setIdAnticipo(tmpArray[0].id) |
||||||
|
setAnticipo(tmpArray[0].anticipo) |
||||||
|
setConcepto(tmpArray[0].concepto) |
||||||
|
setMoneda(tmpArray[0].moneda) |
||||||
|
} |
||||||
|
|
||||||
|
const viewDoc = (idRow: number) => { |
||||||
|
loadRow(idRow) |
||||||
|
setMsgDialogFileManager(true) |
||||||
|
} |
||||||
|
|
||||||
|
const viewDocConta = (idRow: number) => { |
||||||
|
loadRow(idRow) |
||||||
|
setMsgDialogFileManagerConta(true) |
||||||
|
} |
||||||
|
|
||||||
|
const authorizeItem = (id: number) => { |
||||||
|
loadRow(id) |
||||||
|
setMsgDialog(true) |
||||||
|
} |
||||||
|
|
||||||
|
const authorizeAmount = () => { |
||||||
|
const data: DTOAnticiposAutoriza = { |
||||||
|
id: IdAnticipo, |
||||||
|
idUsuario: UserId, |
||||||
|
} |
||||||
|
CAnticiposDataService.Autoriza(data) |
||||||
|
.then((response) => { |
||||||
|
if (response.status == 200) { |
||||||
|
dispatch(updateCorresponsalesAnticipos(response.data)) |
||||||
|
setMsgDialog(false) |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const deleteItem = () => { |
||||||
|
CAnticiposDataService.Delete(IdAnticipo) |
||||||
|
.then((response) => { |
||||||
|
if (response.status == 200) { |
||||||
|
dispatch(deleteCorresponsalesAnticipos(IdAnticipo)) |
||||||
|
setMsgDialog(false) |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
CAnticiposDataService.getAll(props.IDTrafico) |
||||||
|
.then((response) => { |
||||||
|
dispatch(populateCorresponsalesAnticipos(response.data)) |
||||||
|
setFilteredData(mCAnticipos) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
}, [props.IDTrafico]) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
const result = mCAnticipos.filter((row) => row.id > 0 && row.idTrafico === props.IDTrafico) |
||||||
|
}, [mCAnticipos]) |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Container className='labelSize13px'> |
||||||
|
<Row className={props.canDelete ? 'visible' : 'invisible heightZero'}> |
||||||
|
<Col xs='12'> |
||||||
|
<input |
||||||
|
type='text' |
||||||
|
className='form-control genericSelect' |
||||||
|
name='Concepto' |
||||||
|
id='Concepto' |
||||||
|
style={{ height: '30px' }} |
||||||
|
value={Concepto} |
||||||
|
placeholder='Proporcione el concepto' |
||||||
|
onChange={(e) => { |
||||||
|
setConcepto(e.target.value) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row |
||||||
|
style={{ paddingBottom: '5', paddingTop: '15' }} |
||||||
|
className={props.canDelete ? 'visible' : 'invisible heightZero'} |
||||||
|
> |
||||||
|
<Col md='auto' xs={1}> |
||||||
|
<Button |
||||||
|
variant='warning' |
||||||
|
size='sm' |
||||||
|
onClick={() => { |
||||||
|
cleanForm() |
||||||
|
}} |
||||||
|
> |
||||||
|
<BsEraserFill /> |
||||||
|
Limpiar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={3}> |
||||||
|
<Form.Control type='hidden' id='IdAnticipo' size='sm' value={IdAnticipo} placeholder='id' disabled={true} /> |
||||||
|
</Col> |
||||||
|
<Col xs={2}> |
||||||
|
<CurrencyFormat |
||||||
|
value={Anticipo} |
||||||
|
displayType={'input'} |
||||||
|
thousandSeparator={true} |
||||||
|
prefix={'$'} |
||||||
|
onValueChange={(values: any) => { |
||||||
|
const { formattedValue, value } = values |
||||||
|
setAnticipo(value) |
||||||
|
}} |
||||||
|
style={{ |
||||||
|
fontSize: '18px', |
||||||
|
backgroundColor: '#F5FFED', |
||||||
|
border: '2px solid #25D05B', |
||||||
|
width: '150px', |
||||||
|
textAlign: 'right', |
||||||
|
borderRadius: '10px', |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={1}> |
||||||
|
<Form.Control |
||||||
|
as='select' |
||||||
|
className='form-select form-select-sm' |
||||||
|
value={Moneda} |
||||||
|
onChange={(e) => { |
||||||
|
setMoneda(parseInt(e.target.value)) |
||||||
|
}} |
||||||
|
> |
||||||
|
<option value='1'>Pesos</option> |
||||||
|
<option value='2'>Dolares</option> |
||||||
|
</Form.Control> |
||||||
|
</Col> |
||||||
|
<Col xs={2}> |
||||||
|
<Form.Control |
||||||
|
as='select' |
||||||
|
className='form-select form-select-sm' |
||||||
|
value={Financiado} |
||||||
|
onChange={(e) => { |
||||||
|
setFinanciado(parseInt(e.target.value)) |
||||||
|
}} |
||||||
|
> |
||||||
|
<option value='0'>No financiado</option> |
||||||
|
<option value='1'>Financiado</option> |
||||||
|
</Form.Control> |
||||||
|
</Col> |
||||||
|
<Col xs={2}></Col> |
||||||
|
<Col xs={1}> |
||||||
|
<Button |
||||||
|
variant='primary' |
||||||
|
size='sm' |
||||||
|
onClick={() => { |
||||||
|
saveForm() |
||||||
|
}} |
||||||
|
> |
||||||
|
<BsCheckCircle /> |
||||||
|
Guardar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row style={{ paddingBottom: 5 }}> |
||||||
|
<Col xs={12}> |
||||||
|
<div className='ag-theme-alpine' style={{ height: 500, width: '100%' }}> |
||||||
|
<AgGridReact |
||||||
|
rowData={mCAnticipos.filter((p) => p.id !== 0)} |
||||||
|
columnDefs={columnDefs} |
||||||
|
pagination={true} |
||||||
|
paginationAutoPageSize={true} |
||||||
|
ref={gridRef} |
||||||
|
rowSelection={'single'} |
||||||
|
rowMultiSelectWithClick={true} |
||||||
|
/* onRowClicked={(e) => getParams(e)} */ |
||||||
|
></AgGridReact> |
||||||
|
</div> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Container> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
></MsgInformativo> |
||||||
|
<Modal show={msgDialog} onHide={() => setMsgDialog(false)} size='lg'> |
||||||
|
<Modal.Body> |
||||||
|
<Alert variant='primary'> |
||||||
|
¿Esta seguro de eliminar ?: ' |
||||||
|
<br /> <p>{Concepto}</p> |
||||||
|
Por el monto de: |
||||||
|
<span style={{ backgroundColor: 'red', color: 'yellow', fontWeight: 'bold', fontSize: '20px' }}> |
||||||
|
<CurrencyFormat |
||||||
|
value={Anticipo} |
||||||
|
displayType={'text'} |
||||||
|
thousandSeparator={true} |
||||||
|
prefix={'$'} |
||||||
|
decimalScale={2} |
||||||
|
fixedDecimalScale={true} |
||||||
|
/>{' '} |
||||||
|
{Moneda === 1 ? 'Pesos' : 'Dolares'} |
||||||
|
</span> |
||||||
|
</Alert> |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={1}> |
||||||
|
<Button variant='secondary' onClick={() => setMsgDialog(false)} size='sm'> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={5} style={{ paddingLeft: '550px', paddingRight: '0px' }}> |
||||||
|
|
||||||
|
</Col> |
||||||
|
<Col xs={1}> |
||||||
|
<Button variant='primary' onClick={deleteItem} size='sm'> |
||||||
|
Si |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Footer> |
||||||
|
</Modal> |
||||||
|
<Modal show={msgDialog} onHide={() => setMsgDialog(false)} size='lg'> |
||||||
|
<Modal.Body> |
||||||
|
<Alert variant='primary'> |
||||||
|
¿Esta seguro de autorizar? |
||||||
|
<br /> <p>{Concepto}</p> |
||||||
|
Por el monto de: |
||||||
|
<span style={{ backgroundColor: 'red', color: 'yellow', fontWeight: 'bold', fontSize: '20px' }}> |
||||||
|
<CurrencyFormat |
||||||
|
value={Anticipo} |
||||||
|
displayType={'text'} |
||||||
|
thousandSeparator={true} |
||||||
|
prefix={'$'} |
||||||
|
decimalScale={2} |
||||||
|
fixedDecimalScale={true} |
||||||
|
/>{' '} |
||||||
|
{Moneda === 1 ? 'Pesos' : 'Dolares'} |
||||||
|
</span> |
||||||
|
</Alert> |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={1}> |
||||||
|
<Button variant='secondary' onClick={() => setMsgDialog(false)} size='sm'> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={5} style={{ paddingLeft: '550px', paddingRight: '0px' }}> |
||||||
|
|
||||||
|
</Col> |
||||||
|
<Col xs={1}> |
||||||
|
<Button variant='danger' onClick={authorizeAmount} size='sm'> |
||||||
|
Autorizar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Footer> |
||||||
|
</Modal> |
||||||
|
<Modal show={MsgDialogFileManager} onHide={() => setMsgDialogFileManager(false)} size='lg'> |
||||||
|
<Modal.Body> |
||||||
|
<FileManager |
||||||
|
width={750} |
||||||
|
height={200} |
||||||
|
IDProcess={1} |
||||||
|
IdFile={IdAnticipo} |
||||||
|
IDUser={UserId} |
||||||
|
FileName={''} |
||||||
|
canDelete={Depto === 'Contabilidad'} |
||||||
|
FileType={['pdf']} |
||||||
|
Leyenda={'Seleccione el archivo, arrastrelo hasta aqui y sueltelo para subirlo al servidor..'} |
||||||
|
onAppendFM={function (idFile: number): void {}} |
||||||
|
/> |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={11}> </Col> |
||||||
|
<Col xs={1}> |
||||||
|
<Button variant='secondary' onClick={() => setMsgDialogFileManager(false)} size='sm'> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Footer> |
||||||
|
</Modal> |
||||||
|
<Modal show={msgDialogFileManagerConta} onHide={() => setMsgDialogFileManagerConta(false)} size='lg'> |
||||||
|
<Modal.Body> |
||||||
|
<FileManager |
||||||
|
width={750} |
||||||
|
height={200} |
||||||
|
IDProcess={4} |
||||||
|
IdFile={IdAnticipo} |
||||||
|
IDUser={UserId} |
||||||
|
FileName={''} |
||||||
|
canDelete={false} |
||||||
|
FileType={['pdf']} |
||||||
|
Leyenda={'Seleccione el archivo, arrastrelo hasta aqui y sueltelo para subirlo al servidor...'} |
||||||
|
onAppendFM={function (idFile: number): void { |
||||||
|
authorizeAmount() |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={11}> </Col> |
||||||
|
<Col xs={1}> |
||||||
|
<Button variant='secondary' onClick={() => setMsgDialogFileManagerConta(false)} size='sm'> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Footer> |
||||||
|
</Modal> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,269 @@ |
|||||||
|
import { RowClickedEvent } from 'ag-grid-community' |
||||||
|
import { AgGridReact } from 'ag-grid-react' |
||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import { Alert, Button, Card, Col, Form, Modal, Row } from 'react-bootstrap' |
||||||
|
import DataTable from 'react-data-table-component' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import { FaEraser, FaTimesCircle } from 'react-icons/fa' |
||||||
|
import { useDispatch, useSelector } from 'react-redux' |
||||||
|
import ICatProveedores from '../../../Interfaces/Catalogos/ICatProveedores' |
||||||
|
import ProveedoresDataService from '../../../Services/Catalogos/Proveedores.Services' |
||||||
|
import { |
||||||
|
addCatProveedores, |
||||||
|
deleteCatProveedores, |
||||||
|
populateCatProveedores, |
||||||
|
} from '../../../store/features/CatProveedores/CatProveedoresSlice' |
||||||
|
import { RootState } from '../../../store/store' |
||||||
|
import { MsgInformativo } from '../../Utils/Toast/msgInformativo' |
||||||
|
import { ControlledInput } from './ControlledInput/ControlledInput' |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
canDelete: boolean |
||||||
|
clasificacion: number |
||||||
|
} |
||||||
|
|
||||||
|
export const CatProveedores: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch() |
||||||
|
const mProveedores = useSelector((state: RootState) => state.CatProveedores.CatalogoProveedores) |
||||||
|
const [DTData, setDTData] = useState<ICatProveedores[]>([]) |
||||||
|
const [Proveedor, setProveedor] = useState('') |
||||||
|
const [IDProveedor, setIDProveedor] = useState(0) |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msgColor, setMsgColor] = React.useState('primary') |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
const [MsgTime, setMsgTime] = useState(3000) |
||||||
|
const [DialogTabs, setDialogTabs] = useState(false) |
||||||
|
|
||||||
|
const columnsProveedores = [ |
||||||
|
{ |
||||||
|
name: 'id', |
||||||
|
width: '10%', |
||||||
|
selector: (row: ICatProveedores) => row.id, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Proveedor', |
||||||
|
width: '75%', |
||||||
|
cell: (row: ICatProveedores) => { |
||||||
|
return ( |
||||||
|
<ControlledInput |
||||||
|
id={row.id} |
||||||
|
value={row.nombre} |
||||||
|
disabled={false} |
||||||
|
mode={2} |
||||||
|
clasificacion={props.clasificacion} |
||||||
|
/> |
||||||
|
) |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Elimina', |
||||||
|
cell: (row: ICatProveedores) => ( |
||||||
|
<div |
||||||
|
style={{ textAlign: 'center', cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
setIDProveedor(row.id) |
||||||
|
setProveedor(row.nombre) |
||||||
|
setDialogTabs(true) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'red', size: '25px' }}> |
||||||
|
<FaTimesCircle /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
), |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
ProveedoresDataService.getAll(props.clasificacion) |
||||||
|
.then((response) => { |
||||||
|
//setDTData(response.data)
|
||||||
|
dispatch(populateCatProveedores(response.data)) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
}, []) |
||||||
|
|
||||||
|
const cleanForm = () => { |
||||||
|
setIDProveedor(0) |
||||||
|
setProveedor('') |
||||||
|
} |
||||||
|
|
||||||
|
const saveForm = () => { |
||||||
|
const data: ICatProveedores = { |
||||||
|
id: IDProveedor, |
||||||
|
nombre: Proveedor, |
||||||
|
clasificacion: props.clasificacion, |
||||||
|
} |
||||||
|
ProveedoresDataService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
if (response.status == 200) { |
||||||
|
setHeader('Informativo') |
||||||
|
setMsg('El proveedor se agrego exitosamente') |
||||||
|
setShowMsg(true) |
||||||
|
setDialogTabs(false) |
||||||
|
if (data.id === 0) dispatch(addCatProveedores(response.data)) |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const deleteItem = () => { |
||||||
|
ProveedoresDataService.Delete(IDProveedor) |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
setHeader('Informativo') |
||||||
|
setMsg('El provedor se ha eliminado') |
||||||
|
setShowMsg(true) |
||||||
|
setDialogTabs(false) |
||||||
|
dispatch(deleteCatProveedores(IDProveedor)) |
||||||
|
return |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Card style={{}}> |
||||||
|
<Card.Body> |
||||||
|
<Card.Subtitle className='mb-2 text-muted'> |
||||||
|
<Row |
||||||
|
style={{ paddingBottom: '5', paddingTop: '15' }} |
||||||
|
className={props.canDelete ? 'visible' : 'invisible heightZero'} |
||||||
|
> |
||||||
|
<Col |
||||||
|
xs={1} |
||||||
|
style={{ textAlign: 'right', paddingTop: '5px', cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
cleanForm() |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'orange', size: '25px' }}> |
||||||
|
<FaEraser /> |
||||||
|
</IconContext.Provider> |
||||||
|
</Col> |
||||||
|
<Col> |
||||||
|
<Form.Control type='hidden' id='IdItem' size='sm' value={IDProveedor} disabled={true} /> |
||||||
|
</Col> |
||||||
|
<Col xs={1}></Col> |
||||||
|
<Col xs={6}> |
||||||
|
{/* <Form.Control |
||||||
|
type='text' |
||||||
|
id='FacturaTerceros' |
||||||
|
size='sm' |
||||||
|
value={Proveedor} |
||||||
|
placeholder='Proveedor' |
||||||
|
pattern='[a-zA-Z-0-9 ]*' |
||||||
|
onChange={(e) => setProveedor((v) => (e.target.validity.valid ? e.target.value : v))} |
||||||
|
/> */} |
||||||
|
<input |
||||||
|
type='text' |
||||||
|
className='form-control genericSelect' |
||||||
|
name='Proveedor' |
||||||
|
id='Proveedor' |
||||||
|
style={{ height: '30px' }} |
||||||
|
value={Proveedor} |
||||||
|
placeholder='Proporcione el nombre del proveedor' |
||||||
|
onChange={(e) => { |
||||||
|
setProveedor(e.target.value) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={1}></Col> |
||||||
|
<Col xs={1}> |
||||||
|
<Button |
||||||
|
variant='primary' |
||||||
|
size='sm' |
||||||
|
onClick={() => { |
||||||
|
saveForm() |
||||||
|
}} |
||||||
|
> |
||||||
|
Agregar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col> </Col> |
||||||
|
</Row> |
||||||
|
</Card.Subtitle> |
||||||
|
<DataTable |
||||||
|
noHeader |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={columnsProveedores} |
||||||
|
data={mProveedores.filter(function (el) { |
||||||
|
return el.id > 0 |
||||||
|
})} |
||||||
|
/> |
||||||
|
</Card.Body> |
||||||
|
</Card> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
time={MsgTime} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
<Modal |
||||||
|
show={DialogTabs} |
||||||
|
onHide={() => { |
||||||
|
setDialogTabs(false) |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
<Modal.Body> |
||||||
|
<Alert variant='primary'> |
||||||
|
<b>¿Esta seguro de eliminar?</b> |
||||||
|
<br /> |
||||||
|
<h5> {Proveedor} </h5> |
||||||
|
</Alert> |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={6} style={{ textAlign: 'left', paddingRight: '100px' }}> |
||||||
|
<Button |
||||||
|
variant='danger' |
||||||
|
onClick={deleteItem} |
||||||
|
size='sm' |
||||||
|
style={{ paddingRight: '20px', paddingLeft: '20px' }} |
||||||
|
> |
||||||
|
Si |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={6} style={{ textAlign: 'right' }}> |
||||||
|
<Button |
||||||
|
variant='secondary' |
||||||
|
onClick={() => { |
||||||
|
setDialogTabs(false) |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Footer> |
||||||
|
</Modal> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,77 @@ |
|||||||
|
import React, { FC, useState } from 'react' |
||||||
|
import { MsgInformativo } from '../../../Utils/Toast/msgInformativo' |
||||||
|
import ProvDataService from '../../../../Services/Catalogos/Proveedores.Services' |
||||||
|
import { useDispatch } from 'react-redux' |
||||||
|
import ICatProveedores from '../../../../Interfaces/Catalogos/ICatProveedores' |
||||||
|
import { updateCatProveedores } from '../../../../store/features/CatProveedores/CatProveedoresSlice' |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
id: number |
||||||
|
value: any |
||||||
|
disabled?: boolean |
||||||
|
mode: number // 1: Number, 2: String
|
||||||
|
clasificacion: number |
||||||
|
} |
||||||
|
|
||||||
|
export const ControlledInput: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch() |
||||||
|
const [id, setid] = useState(props.id) |
||||||
|
const [value, setValue] = useState(props.value) |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msgColor, setMsgColor] = React.useState('primary') |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
|
||||||
|
const onChange = (event: any) => { |
||||||
|
setValue(event.target.value) |
||||||
|
} |
||||||
|
const handleKeyDown = (event: any) => { |
||||||
|
if (event.key === 'Enter') { |
||||||
|
if (isNaN(event.target.value) && props.mode === 1) { |
||||||
|
alert('Valor no valido!') |
||||||
|
return |
||||||
|
} |
||||||
|
const data: ICatProveedores = { |
||||||
|
id: id, |
||||||
|
nombre: value, |
||||||
|
clasificacion: props.clasificacion, |
||||||
|
} |
||||||
|
ProvDataService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
if (response.status == 200) { |
||||||
|
dispatch(updateCatProveedores(response.data)) |
||||||
|
setHeader('Informativo') |
||||||
|
setMsg('La informacion se guardo exitosamente') |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
return ( |
||||||
|
<> |
||||||
|
<input |
||||||
|
value={value} |
||||||
|
onChange={onChange} |
||||||
|
disabled={false} |
||||||
|
onKeyDown={(e) => handleKeyDown(e)} |
||||||
|
style={{ width: '75%' }} |
||||||
|
/> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,252 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import { Button, Card, Col, Form, Row } from 'react-bootstrap' |
||||||
|
import DataTable from 'react-data-table-component' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import { FaEraser, FaTimesCircle } from 'react-icons/fa' |
||||||
|
import { useDispatch, useSelector } from 'react-redux' |
||||||
|
import ICorresponsalContenedores from '../../../Interfaces/Corresponsales/ICorresponsalContenedores' |
||||||
|
import CConDataService from '../../../Services/Corresponsalias/Corresponsales.Contenedores.Services' |
||||||
|
import { RootState } from '../../../store/store' |
||||||
|
import { MsgInformativo } from '../../Utils/Toast/msgInformativo' |
||||||
|
import CContDataService from '../../../Services/Corresponsalias/Corresponsales.Contenedores.Services' |
||||||
|
import { |
||||||
|
addCorresponsalesContenedores, |
||||||
|
deleteCorresponsalesContenedores, |
||||||
|
} from '../../../store/features/Corresponsales/CorresponsalesContenedoresSlice' |
||||||
|
import { ControlledInput } from './ControlledInput/ControlledInput' |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
IDTrafico: number |
||||||
|
canDelete: boolean |
||||||
|
} |
||||||
|
|
||||||
|
export const Contenedores: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch() |
||||||
|
const mCContenedores = useSelector((state: RootState) => state.CCData.CorresponsalesContenedores) |
||||||
|
const [DTData, setDTData] = useState<ICorresponsalContenedores[]>([]) |
||||||
|
const [Contenedor, setContenedor] = useState('') |
||||||
|
const [IDContenedor, setIDContenedor] = useState(0) |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msgColor, setMsgColor] = React.useState('primary') |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
const [DialogTabs, setDialogTabs] = useState(false) |
||||||
|
|
||||||
|
const columnsConcepts = [ |
||||||
|
{ |
||||||
|
name: 'id', |
||||||
|
width: '10%', |
||||||
|
selector: (row: ICorresponsalContenedores) => row.id, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Contenedor', |
||||||
|
width: '75%', |
||||||
|
cell: (row: ICorresponsalContenedores) => { |
||||||
|
return ( |
||||||
|
<ControlledInput id={row.id} value={row.contenedor} disabled={false} mode={2} IDTrafico={props.IDTrafico} /> |
||||||
|
) |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Elimina', |
||||||
|
cell: (row: ICorresponsalContenedores) => ( |
||||||
|
<div |
||||||
|
style={{ textAlign: 'center', cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
setIDContenedor(row.id) |
||||||
|
setContenedor(row.contenedor) |
||||||
|
setDialogTabs(true) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'red', size: '25px' }}> |
||||||
|
<FaTimesCircle /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
), |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
CConDataService.getAll(props.IDTrafico) |
||||||
|
.then((response) => { |
||||||
|
setDTData(response.data) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
}, []) |
||||||
|
|
||||||
|
const saveForm = () => { |
||||||
|
const data: ICorresponsalContenedores = { |
||||||
|
id: IDContenedor, |
||||||
|
contenedor: Contenedor, |
||||||
|
idTrafico: props.IDTrafico, |
||||||
|
fSemaforo: '', |
||||||
|
semaforo: 0, |
||||||
|
} |
||||||
|
CContDataService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
if (response.status == 200) { |
||||||
|
if (data.id === 0) dispatch(addCorresponsalesContenedores(response.data)) |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const deleteItem = () => { |
||||||
|
CConDataService.Delete(IDContenedor) |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
setHeader('Informativo') |
||||||
|
setMsg(response.data.respuesta) |
||||||
|
setShowMsg(true) |
||||||
|
setDialogTabs(false) |
||||||
|
dispatch(deleteCorresponsalesContenedores(IDContenedor)) |
||||||
|
return |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const cleanForm = () => { |
||||||
|
setContenedor('') |
||||||
|
setIDContenedor(0) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Card style={{}}> |
||||||
|
<Card.Body> |
||||||
|
<Card.Subtitle className='mb-2 text-muted'> |
||||||
|
<Row |
||||||
|
style={{ paddingBottom: '5', paddingTop: '15' }} |
||||||
|
className={props.canDelete ? 'visible' : 'invisible heightZero'} |
||||||
|
> |
||||||
|
<Col |
||||||
|
xs={1} |
||||||
|
style={{ textAlign: 'right', paddingTop: '5px', cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
cleanForm() |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'orange', size: '25px' }}> |
||||||
|
<FaEraser /> |
||||||
|
</IconContext.Provider> |
||||||
|
</Col> |
||||||
|
<Col> |
||||||
|
<Form.Control |
||||||
|
type='hidden' |
||||||
|
id='IdItem' |
||||||
|
size='sm' |
||||||
|
value={IDContenedor} |
||||||
|
placeholder='Contenedor' |
||||||
|
disabled={true} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={1}></Col> |
||||||
|
<Col xs={6}> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
id='Contenedor' |
||||||
|
size='sm' |
||||||
|
value={Contenedor} |
||||||
|
placeholder='Contenedor' |
||||||
|
pattern='[a-zA-Z-0-9 ]*' |
||||||
|
onChange={(e) => setContenedor((v) => (e.target.validity.valid ? e.target.value : v))} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={1}></Col> |
||||||
|
<Col xs={1}> |
||||||
|
<Button |
||||||
|
variant='primary' |
||||||
|
size='sm' |
||||||
|
onClick={() => { |
||||||
|
saveForm() |
||||||
|
}} |
||||||
|
> |
||||||
|
Agregar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col> </Col> |
||||||
|
</Row> |
||||||
|
</Card.Subtitle> |
||||||
|
<DataTable |
||||||
|
noHeader |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={columnsConcepts} |
||||||
|
data={mCContenedores.filter(function (el) { |
||||||
|
return el.id > 0 |
||||||
|
})} |
||||||
|
/> |
||||||
|
</Card.Body> |
||||||
|
</Card> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
time={2000} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
{/* <Modal |
||||||
|
show={DialogTabs} |
||||||
|
onHide={() => { |
||||||
|
setDialogTabs(false) |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
<Modal.Body> |
||||||
|
<Alert variant='primary'> |
||||||
|
<b>¿Esta seguro de eliminar?</b> |
||||||
|
<br /> |
||||||
|
<h5> {Contenedor} </h5> |
||||||
|
</Alert> |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={6} style={{ textAlign: 'left', paddingRight: '100px' }}> |
||||||
|
<Button |
||||||
|
variant='danger' |
||||||
|
onClick={deleteItem} |
||||||
|
size='sm' |
||||||
|
style={{ paddingRight: '20px', paddingLeft: '20px' }} |
||||||
|
> |
||||||
|
Si |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={6} style={{ textAlign: 'right' }}> |
||||||
|
<Button |
||||||
|
variant='secondary' |
||||||
|
onClick={() => { |
||||||
|
setDialogTabs(false) |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Footer> |
||||||
|
</Modal> */} |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,79 @@ |
|||||||
|
import React, { FC, useState } from 'react' |
||||||
|
import ICorresponsalContenedores from '../../../../Interfaces/Corresponsales/ICorresponsalContenedores' |
||||||
|
import { MsgInformativo } from '../../../Utils/Toast/msgInformativo' |
||||||
|
import CContDataService from '../../../../Services/Corresponsalias/Corresponsales.Contenedores.Services' |
||||||
|
import { updateCorresponsalesContenedores } from '../../../../store/features/Corresponsales/CorresponsalesContenedoresSlice' |
||||||
|
import { useDispatch } from 'react-redux' |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
id: number |
||||||
|
value: any |
||||||
|
disabled?: boolean |
||||||
|
mode: number // 1: Number, 2: String
|
||||||
|
IDTrafico: number |
||||||
|
} |
||||||
|
|
||||||
|
export const ControlledInput: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch() |
||||||
|
const [id, setid] = useState(props.id) |
||||||
|
const [value, setValue] = useState(props.value) |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msgColor, setMsgColor] = React.useState('primary') |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
|
||||||
|
const onChange = (event: any) => { |
||||||
|
setValue(event.target.value) |
||||||
|
} |
||||||
|
const handleKeyDown = (event: any) => { |
||||||
|
if (event.key === 'Enter') { |
||||||
|
if (isNaN(event.target.value) && props.mode === 1) { |
||||||
|
alert('Valor no valido!') |
||||||
|
return |
||||||
|
} |
||||||
|
const data: ICorresponsalContenedores = { |
||||||
|
id: id, |
||||||
|
contenedor: value, |
||||||
|
idTrafico: props.IDTrafico, |
||||||
|
fSemaforo: '', |
||||||
|
semaforo: 0, |
||||||
|
} |
||||||
|
CContDataService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
if (response.status == 200) { |
||||||
|
dispatch(updateCorresponsalesContenedores(response.data)) |
||||||
|
setHeader('Informativo') |
||||||
|
setMsg('La informacion se guardo exitosamente') |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
return ( |
||||||
|
<> |
||||||
|
<input |
||||||
|
value={value} |
||||||
|
onChange={onChange} |
||||||
|
disabled={props.disabled} |
||||||
|
onKeyDown={(e) => handleKeyDown(e)} |
||||||
|
style={{ width: '75%' }} |
||||||
|
/> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,326 @@ |
|||||||
|
import { FC, useEffect, useState } from 'react' |
||||||
|
import { useDispatch, useSelector } from 'react-redux' |
||||||
|
import { RootState } from '../../../store/store' |
||||||
|
import CContDataService from '../../../Services/Corresponsalias/Corresponsales.Contenedores.Services' |
||||||
|
import ICorresponsalContenedores from '../../../Interfaces/Corresponsales/ICorresponsalContenedores' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import { BsFillCalendarCheckFill, BsFillCalendarDayFill, BsFillRecordFill, BsFillXCircleFill } from 'react-icons/bs' |
||||||
|
import { |
||||||
|
deleteCorresponsalesContenedores, |
||||||
|
updateCorresponsalesContenedores, |
||||||
|
} from '../../../store/features/Corresponsales/CorresponsalesContenedoresSlice' |
||||||
|
import { Alert, Button, Col, Form, Modal, Row } from 'react-bootstrap' |
||||||
|
import DatePicker from 'react-datepicker' |
||||||
|
import 'react-datepicker/dist/react-datepicker.css' |
||||||
|
import { isTypeNode } from 'typescript' |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
IDTrafico: number |
||||||
|
Editable: boolean |
||||||
|
} |
||||||
|
|
||||||
|
export const SelectContainer: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch() |
||||||
|
const [toggleSelect, setToggleSelect] = useState(false) |
||||||
|
const mCContenedores = useSelector((state: RootState) => state.CCData.CorresponsalesContenedores) |
||||||
|
const [Contenedor, setContenedor] = useState('') |
||||||
|
const [IDContenedor, setIDContenedor] = useState(0) |
||||||
|
const [Placeholder, setPlaceholder] = useState('') |
||||||
|
const [DialogTabs, setDialogTabs] = useState(false) |
||||||
|
const [DialogAddDate, setDialogAddDate] = useState(false) |
||||||
|
const [FSemaforo, setFSemaforo] = useState<Date | null>() |
||||||
|
const [Semaforo, setSemaforo] = useState(0) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
setPlaceholder('(' + mCContenedores.filter((item) => item.id > 0).length + ') Contenedores') |
||||||
|
}, [mCContenedores]) |
||||||
|
|
||||||
|
const loadInfo = (data: ICorresponsalContenedores) => { |
||||||
|
setIDContenedor(data.id) |
||||||
|
setContenedor(data.contenedor) |
||||||
|
} |
||||||
|
|
||||||
|
const handleKeyDown = (event: any) => { |
||||||
|
if (event.key === 'Enter') { |
||||||
|
const data: ICorresponsalContenedores = { |
||||||
|
id: IDContenedor, |
||||||
|
contenedor: Contenedor, |
||||||
|
idTrafico: props.IDTrafico, |
||||||
|
fSemaforo: FSemaforo ? adjustTimeZone(FSemaforo.toISOString()) : '', |
||||||
|
semaforo: Semaforo, |
||||||
|
} |
||||||
|
CContDataService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
dispatch(updateCorresponsalesContenedores(response.data)) |
||||||
|
setContenedor('') |
||||||
|
setToggleSelect(true) |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const adjustTimeZone = (str: string): string => { |
||||||
|
if (str) { |
||||||
|
const original: any = new Date(str) |
||||||
|
const real = new Date(original - original.getTimezoneOffset() * 60 * 1000) |
||||||
|
return real.toISOString() |
||||||
|
} else return '' |
||||||
|
} |
||||||
|
|
||||||
|
const updateItem = () => { |
||||||
|
const data: ICorresponsalContenedores = { |
||||||
|
id: IDContenedor, |
||||||
|
contenedor: Contenedor, |
||||||
|
idTrafico: props.IDTrafico, |
||||||
|
fSemaforo: FSemaforo ? adjustTimeZone(FSemaforo.toISOString()) : '', |
||||||
|
semaforo: Semaforo, |
||||||
|
} |
||||||
|
// console.log(JSON.stringify(data))
|
||||||
|
CContDataService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
setIDContenedor(0) |
||||||
|
setContenedor('') |
||||||
|
setDialogTabs(false) |
||||||
|
dispatch(updateCorresponsalesContenedores(response.data)) |
||||||
|
return |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const StrtoDate = (str: string): Date | null => { |
||||||
|
if (str) { |
||||||
|
const original: any = new Date(str) |
||||||
|
return original |
||||||
|
} else return null |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<div className='form-group'> |
||||||
|
<div className='col-sm-12 parent'> |
||||||
|
<div className='input-group'> |
||||||
|
<input type='hidden' className='form-control' name='IDContenedor' id='IDContenedor' value={IDContenedor} /> |
||||||
|
<span className='input-group-addon sorroundImage'> |
||||||
|
<img |
||||||
|
src='http://reportes.gemcousa.com/images/Clean.png' |
||||||
|
width='28' |
||||||
|
height='28' |
||||||
|
style={{ cursor: 'pointer' }} |
||||||
|
alt='' |
||||||
|
onClick={() => { |
||||||
|
setIDContenedor(0) |
||||||
|
setContenedor('') |
||||||
|
}} |
||||||
|
/> |
||||||
|
</span> |
||||||
|
<input |
||||||
|
type='text' |
||||||
|
className='form-control genericSelect' |
||||||
|
name='Contenedor' |
||||||
|
id='Contenedor' |
||||||
|
style={{ height: '30px' }} |
||||||
|
value={Contenedor} |
||||||
|
placeholder={Placeholder} |
||||||
|
disabled={!props.Editable} |
||||||
|
onChange={(e) => { |
||||||
|
setContenedor(e.target.value) |
||||||
|
}} |
||||||
|
onKeyDown={(e) => handleKeyDown(e)} |
||||||
|
/> |
||||||
|
<span className='input-group-addon sorroundImage'> |
||||||
|
<img |
||||||
|
src='http://reportes.gemcousa.com/images/caret.png' |
||||||
|
width='28' |
||||||
|
height='28' |
||||||
|
style={{ cursor: 'pointer' }} |
||||||
|
alt='' |
||||||
|
onClick={() => { |
||||||
|
setToggleSelect(!toggleSelect) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</span> |
||||||
|
<div className='child' style={toggleSelect ? { visibility: 'visible' } : { visibility: 'hidden' }}> |
||||||
|
<ul className='cleanLi'> |
||||||
|
{mCContenedores |
||||||
|
? mCContenedores |
||||||
|
.map((item, index) => { |
||||||
|
return item.id > 0 ? ( |
||||||
|
<li key={item.id} onClick={() => loadInfo(item)}> |
||||||
|
<span |
||||||
|
onClick={() => { |
||||||
|
setDialogTabs(true) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'red', size: '15px' }}> |
||||||
|
<BsFillXCircleFill /> |
||||||
|
</IconContext.Provider> |
||||||
|
</span> |
||||||
|
<span style={{ paddingLeft: '10px' }}>{item.contenedor}</span> |
||||||
|
<span |
||||||
|
onClick={() => { |
||||||
|
setFSemaforo(StrtoDate(item.fSemaforo)) |
||||||
|
setSemaforo(item.semaforo) |
||||||
|
setDialogAddDate(true) |
||||||
|
}} |
||||||
|
> |
||||||
|
| {item.fSemaforo} |{' '} |
||||||
|
{item.fSemaforo ? ( |
||||||
|
item.semaforo === 1 ? ( |
||||||
|
<IconContext.Provider value={{ color: 'red', size: '20px' }}> |
||||||
|
<BsFillRecordFill /> |
||||||
|
</IconContext.Provider> |
||||||
|
) : ( |
||||||
|
<IconContext.Provider value={{ color: '#4BFF59', size: '20px' }}> |
||||||
|
<BsFillRecordFill /> |
||||||
|
</IconContext.Provider> |
||||||
|
) |
||||||
|
) : ( |
||||||
|
'' |
||||||
|
)} |
||||||
|
<span |
||||||
|
style={{ |
||||||
|
paddingLeft: '20px', |
||||||
|
visibility: props.Editable && toggleSelect ? 'visible' : 'hidden', |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'green', size: '15px' }}> |
||||||
|
<BsFillCalendarCheckFill /> |
||||||
|
</IconContext.Provider> |
||||||
|
</span> |
||||||
|
</span> |
||||||
|
</li> |
||||||
|
) : ( |
||||||
|
'' |
||||||
|
) |
||||||
|
}) |
||||||
|
.reverse() |
||||||
|
: ''} |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<Modal |
||||||
|
show={DialogTabs} |
||||||
|
onHide={() => { |
||||||
|
setDialogTabs(false) |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
<Modal.Body> |
||||||
|
<Alert variant='primary'> |
||||||
|
<b>¿Esta seguro de eliminar?</b> |
||||||
|
<br /> |
||||||
|
<h5> {Contenedor} </h5> |
||||||
|
</Alert> |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={6} style={{ textAlign: 'left', paddingRight: '100px' }}> |
||||||
|
<Button |
||||||
|
variant='danger' |
||||||
|
onClick={updateItem} |
||||||
|
size='sm' |
||||||
|
style={{ paddingRight: '20px', paddingLeft: '20px' }} |
||||||
|
> |
||||||
|
Si |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={6} style={{ textAlign: 'right' }}> |
||||||
|
<Button |
||||||
|
variant='secondary' |
||||||
|
onClick={() => { |
||||||
|
setDialogTabs(false) |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Footer> |
||||||
|
</Modal> |
||||||
|
|
||||||
|
<Modal |
||||||
|
show={DialogAddDate} |
||||||
|
onHide={() => { |
||||||
|
setDialogTabs(false) |
||||||
|
}} |
||||||
|
/* size='sm' */ |
||||||
|
> |
||||||
|
<Modal.Body> |
||||||
|
<Alert variant='primary'> |
||||||
|
<Row> |
||||||
|
<Col xs={12}> |
||||||
|
<b>¿Esta seguro de agregar fecha al contenedor: {Contenedor}?</b> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row style={{ paddingTop: '10px' }}> |
||||||
|
<Col xs={4}></Col> |
||||||
|
<Col xs={2}>Fecha</Col> |
||||||
|
<Col xs={6}> |
||||||
|
<DatePicker |
||||||
|
selected={FSemaforo} |
||||||
|
onChange={(date: any) => setFSemaforo(date)} |
||||||
|
showTimeSelect |
||||||
|
dateFormat='MM/dd/yyyy HH:mm:ss' |
||||||
|
placeholderText='No definido' |
||||||
|
isClearable |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row style={{ paddingTop: '10px' }}> |
||||||
|
<Col xs={5}></Col> |
||||||
|
<Col xs={2}>Semaforo</Col> |
||||||
|
<Col xs={5}> |
||||||
|
<Form.Control |
||||||
|
as='select' |
||||||
|
onChange={(e) => { |
||||||
|
setSemaforo(parseInt(e.target.value)) |
||||||
|
}} |
||||||
|
value={Semaforo} |
||||||
|
className='form-select form-select-sm' |
||||||
|
> |
||||||
|
<option value='0'>-SELECCIONE-</option> |
||||||
|
<option value='1'>Rojo</option> |
||||||
|
<option value='2'>Verde</option> |
||||||
|
</Form.Control> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Alert> |
||||||
|
<Row> |
||||||
|
<Col xs={6} style={{ textAlign: 'left', paddingRight: '100px' }}> |
||||||
|
<Button |
||||||
|
variant='primary' |
||||||
|
onClick={updateItem} |
||||||
|
size='sm' |
||||||
|
style={{ paddingRight: '20px', paddingLeft: '20px' }} |
||||||
|
> |
||||||
|
Guardar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={6} style={{ textAlign: 'right' }}> |
||||||
|
<Button |
||||||
|
variant='secondary' |
||||||
|
onClick={() => { |
||||||
|
setDialogAddDate(false) |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Body> |
||||||
|
</Modal> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,569 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import { Alert, Card, Col, FloatingLabel, Form, Modal, Row } from 'react-bootstrap' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import { BsCloudArrowUpFill, BsFillPlusCircleFill } from 'react-icons/bs' |
||||||
|
import FileManager from '../../Utils/FileManager/FileManager' |
||||||
|
import CuentasComplementariasDS from '../../../Services/Corresponsalias/Corresponsales.CuentasComplementarias.Services' |
||||||
|
import MFileManagerDataService from '../../../Services/Utils/MFileManager.Service' |
||||||
|
import ICorresponsalCuentasComplementarias from '../../../Interfaces/Corresponsales/ICorresponsalCuentasComplementarias' |
||||||
|
import { MsgInformativo } from '../../Utils/Toast/msgInformativo' |
||||||
|
import DataTable from 'react-data-table-component' |
||||||
|
import DTOCorresponsalCuentaComplementaria from '../../../DTO/Corresponsales/DTOCuentaComplementaria' |
||||||
|
import { SelectEstatus } from './SelectEstatus/SelectEstatus' |
||||||
|
import { FcAbout } from 'react-icons/fc' |
||||||
|
import DTOLogCorresponsalComplementariaEstatus from '../../../DTO/Corresponsales/DTOLogCorresponsalComplementariaEstatus' |
||||||
|
import FileManagerDS from '../../../Services/Utils/FileManager.Services' |
||||||
|
import { AiOutlineClose } from 'react-icons/ai' |
||||||
|
import { MdCloudUpload, MdOutlineInventory, MdOutlineSave } from 'react-icons/md' |
||||||
|
import { useDispatch, useSelector } from 'react-redux' |
||||||
|
import { RootState } from '../../../store/store' |
||||||
|
import { FiSave } from 'react-icons/fi' |
||||||
|
import ICorresponsalCuentaComplementariaStatus from '../../../Interfaces/Corresponsales/ICorresponsalCuentaComplementariaEstatus' |
||||||
|
import { updateCorresponsalesCuentasComplementariasEstatus } from '../../../store/features/Corresponsales/CorresponsalesCuentasComplementariasEstatusSlice' |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
IDTrafico: number |
||||||
|
UserId: number |
||||||
|
} |
||||||
|
|
||||||
|
export const CuentasComplementarias: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch() |
||||||
|
const [Depto, setDepto] = useState(() => { |
||||||
|
const stickyValue = window.localStorage.getItem('Departamento') |
||||||
|
return stickyValue !== null ? JSON.parse(stickyValue) : '' |
||||||
|
}) |
||||||
|
const mCCCEstatus = useSelector( |
||||||
|
(state: RootState) => state.CCueCompEstatus.CorresponsalesCuentasComplementariasEstatus |
||||||
|
) |
||||||
|
const [showModal, setShowModal] = useState(false) |
||||||
|
const [showModalLog, setShowModalLog] = useState(false) |
||||||
|
const [showModalCatalogo, setShowModalCatalogo] = useState(false) |
||||||
|
const [DTData, setDTData] = useState<ICorresponsalCuentasComplementarias[]>([]) |
||||||
|
const [CuentaComplementaria, setCuentaComplementaria] = useState<ICorresponsalCuentasComplementarias[]>([]) |
||||||
|
const [HistorialEstatus, setHistoriaEstatus] = useState<DTOLogCorresponsalComplementariaEstatus[]>([]) |
||||||
|
const [IDCuentaComplementaria, setIdCuentaComplementarias] = useState(0) |
||||||
|
const [IDPDF, setIDPDF] = useState(0) |
||||||
|
const [IDXML, setIDXML] = useState(0) |
||||||
|
const [IDEstatus, setIDEstatus] = useState(0) |
||||||
|
const [Estatus, setEstatus] = useState('') |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msgColor, setMsgColor] = React.useState('primary') |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
const [MsgTime, setMsgTime] = useState(3000) |
||||||
|
|
||||||
|
const colCuentasComplementarias = [ |
||||||
|
{ |
||||||
|
name: 'id', |
||||||
|
width: '60px', |
||||||
|
selector: (row: ICorresponsalCuentasComplementarias) => row.id, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: '', |
||||||
|
width: '20px', |
||||||
|
cell: (row: ICorresponsalCuentasComplementarias) => { |
||||||
|
return row.archivoXML ? ( |
||||||
|
<div |
||||||
|
style={{ |
||||||
|
cursor: 'pointer', |
||||||
|
visibility: Depto === 'Corresponsalias' && row.estatus !== 7 ? 'visible' : 'hidden', |
||||||
|
}} |
||||||
|
onClick={() => { |
||||||
|
clearFile(row.id, 1, row.idXML) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'red', size: '15px' }}> |
||||||
|
<AiOutlineClose /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
) : ( |
||||||
|
<div |
||||||
|
style={{ cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
setPreloader(row.id) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'blue', size: '25px' }}> |
||||||
|
<MdCloudUpload /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
) |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'XML', |
||||||
|
width: '300px', |
||||||
|
cell: (row: ICorresponsalCuentasComplementarias) => { |
||||||
|
return ( |
||||||
|
<div |
||||||
|
style={{ cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
getFileContent(row.idXML, 22, row.archivoXML) |
||||||
|
}} |
||||||
|
> |
||||||
|
{row.archivoXML} |
||||||
|
</div> |
||||||
|
) |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: '', |
||||||
|
width: '20px', |
||||||
|
cell: (row: ICorresponsalCuentasComplementarias) => { |
||||||
|
return row.archivoPDF ? ( |
||||||
|
<div |
||||||
|
style={{ |
||||||
|
cursor: 'pointer', |
||||||
|
visibility: Depto === 'Corresponsalias' && row.estatus !== 7 ? 'visible' : 'hidden', |
||||||
|
}} |
||||||
|
onClick={() => { |
||||||
|
clearFile(row.id, 2, row.idPDF) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'red', size: '15px' }}> |
||||||
|
<AiOutlineClose /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
) : ( |
||||||
|
<div |
||||||
|
style={{ cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
setPreloader(row.id) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'blue', size: '25px' }}> |
||||||
|
<MdCloudUpload /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
) |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'PDF', |
||||||
|
width: '300px', |
||||||
|
cell: (row: ICorresponsalCuentasComplementarias) => { |
||||||
|
return ( |
||||||
|
<div |
||||||
|
style={{ cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
getFileContent(row.idPDF, 21, row.archivoPDF) |
||||||
|
}} |
||||||
|
> |
||||||
|
{row.archivoPDF} |
||||||
|
</div> |
||||||
|
) |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Estatus', |
||||||
|
width: '400px', |
||||||
|
cell: (row: ICorresponsalCuentasComplementarias) => { |
||||||
|
return <SelectEstatus IDEstatus={row.estatus} IDCuenta={row.id} Enabled={row.estatus === 7} /> |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Historico', |
||||||
|
width: '110px', |
||||||
|
cell: (row: ICorresponsalCuentasComplementarias) => ( |
||||||
|
<div |
||||||
|
style={{ textAlign: 'center', cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
showHistoricoEstatus(row.id) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'red', size: '25px' }}> |
||||||
|
<FcAbout /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
), |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
const setPreloader = (id: number) => { |
||||||
|
setIdCuentaComplementarias(id) |
||||||
|
setIDPDF(0) |
||||||
|
setIDXML(0) |
||||||
|
setShowModal(true) |
||||||
|
} |
||||||
|
|
||||||
|
const clearFile = (IDCuenta: number, witchFile: number, idFile: number) => { |
||||||
|
CuentasComplementariasDS.ClearFile(IDCuenta, witchFile) |
||||||
|
.then((response) => { |
||||||
|
FileManagerDS.DeleteFile(idFile) |
||||||
|
.then((response) => { |
||||||
|
loadCuentaComplementaria() |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const createCuentaComplementaria = () => { |
||||||
|
const data: DTOCorresponsalCuentaComplementaria = { |
||||||
|
id: 0, |
||||||
|
idTrafico: props.IDTrafico, |
||||||
|
idFile: 0, |
||||||
|
} |
||||||
|
CuentasComplementariasDS.Append(data) |
||||||
|
.then((response) => { |
||||||
|
// setCuentaComplementaria(response.data)
|
||||||
|
setIdCuentaComplementarias(response.data.id) |
||||||
|
setIDPDF(response.data.idPDF) |
||||||
|
setIDXML(response.data.idXML) |
||||||
|
setShowModal(true) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const loadCuentaComplementaria = () => { |
||||||
|
CuentasComplementariasDS.Get(props.IDTrafico) |
||||||
|
.then((response) => { |
||||||
|
setDTData(response.data) |
||||||
|
setIDPDF(0) |
||||||
|
setIDXML(0) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
setIDPDF(0) |
||||||
|
setIDXML(0) |
||||||
|
}, [IDCuentaComplementaria]) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
loadCuentaComplementaria() |
||||||
|
}, []) |
||||||
|
|
||||||
|
const showHistoricoEstatus = (id: number) => { |
||||||
|
CuentasComplementariasDS.GetLogEstatus(id) |
||||||
|
.then((response) => { |
||||||
|
setHistoriaEstatus(response.data) |
||||||
|
setShowModalLog(true) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const updateFile = (idFile: number) => { |
||||||
|
if (IDCuentaComplementaria === 0) { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Para proceder, es necesario que cree una cuenta complementaria o seleccione una existente') |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
} |
||||||
|
const data: DTOCorresponsalCuentaComplementaria = { |
||||||
|
id: IDCuentaComplementaria, |
||||||
|
idFile: idFile, |
||||||
|
idTrafico: props.IDTrafico, |
||||||
|
} |
||||||
|
CuentasComplementariasDS.Append(data) |
||||||
|
.then((response) => { |
||||||
|
loadCuentaComplementaria() |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const getFileContent = (id: number, proceso: number, archivo: string) => { |
||||||
|
if (id > 0) { |
||||||
|
MFileManagerDataService.getFileContentById(id, proceso) |
||||||
|
.then((response: any) => { |
||||||
|
if (response.status === 200) { |
||||||
|
if (archivo.toLowerCase().endsWith('.pdf')) { |
||||||
|
console.log(response.data) |
||||||
|
const blob = new Blob([response.data], { type: 'application/pdf' }) |
||||||
|
const url = window.URL.createObjectURL(blob) |
||||||
|
window.open(url) |
||||||
|
} else if (archivo.toLowerCase().endsWith('.xml')) { |
||||||
|
console.log(response.data) |
||||||
|
const blob = new Blob([response.data], { type: 'application/xml' }) |
||||||
|
const url = window.URL.createObjectURL(blob) |
||||||
|
window.open(url) |
||||||
|
} |
||||||
|
} else { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('No existe ningun archivo asignado') |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('A este concepto no se le ha anexado archivo') |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const saveEstatus = () => { |
||||||
|
const data: ICorresponsalCuentaComplementariaStatus = { |
||||||
|
id: IDEstatus, |
||||||
|
estatus: Estatus, |
||||||
|
} |
||||||
|
CuentasComplementariasDS.AppendEstatus(data) |
||||||
|
.then((response) => { |
||||||
|
dispatch(updateCorresponsalesCuentasComplementariasEstatus(response.data)) |
||||||
|
setIDEstatus(0) |
||||||
|
setEstatus('') |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Row> |
||||||
|
<Col style={{ textAlign: 'right', visibility: Depto === 'Contabilidad' ? 'visible' : 'hidden' }}> |
||||||
|
<div |
||||||
|
style={{ cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
setShowModalCatalogo(true) |
||||||
|
}} |
||||||
|
title='De un click aqui para agregar abrir el catalogo de conceptos de rechazo' |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'green', size: '35px' }}> |
||||||
|
<MdOutlineInventory /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
</Col> |
||||||
|
<Col xs={10}></Col> |
||||||
|
<Col style={{ visibility: Depto !== 'Contabilidad' ? 'visible' : 'hidden' }}> |
||||||
|
<div |
||||||
|
style={{ cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
createCuentaComplementaria() |
||||||
|
}} |
||||||
|
title='De un click aqui para agregar una nueva cuenta complementaria' |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'green', size: '35px' }}> |
||||||
|
<BsFillPlusCircleFill /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row style={{ paddingTop: '10px' }}> |
||||||
|
<Card> |
||||||
|
<Col xs={12}> |
||||||
|
<DataTable |
||||||
|
noHeader |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={colCuentasComplementarias} |
||||||
|
data={DTData} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Card> |
||||||
|
</Row> |
||||||
|
<Modal |
||||||
|
show={showModal} |
||||||
|
onHide={() => { |
||||||
|
setShowModal(false) |
||||||
|
}} |
||||||
|
size={'sm'} |
||||||
|
dialogClassName={'modal-50w'} |
||||||
|
> |
||||||
|
<Modal.Body> |
||||||
|
<Row> |
||||||
|
<Col xs={6}> |
||||||
|
<FileManager |
||||||
|
IDUser={props.UserId} |
||||||
|
width={350} |
||||||
|
height={200} |
||||||
|
IDProcess={22} |
||||||
|
IdFile={IDCuentaComplementaria} |
||||||
|
FileName={''} |
||||||
|
canDelete={true} |
||||||
|
FileType={['xml']} |
||||||
|
Leyenda={'Seleccione el archivo XML, arrastrelo hasta aqui y sueltelo para subirlo al servidor...'} |
||||||
|
onAppendFM={function (idFile: number): void { |
||||||
|
setIDXML(idFile) |
||||||
|
updateFile(idFile) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={6}> |
||||||
|
<FileManager |
||||||
|
IDUser={props.UserId} |
||||||
|
width={350} |
||||||
|
height={200} |
||||||
|
IDProcess={21} |
||||||
|
IdFile={IDCuentaComplementaria} |
||||||
|
FileName={''} |
||||||
|
canDelete={true} |
||||||
|
FileType={['pdf']} |
||||||
|
Leyenda={'Seleccione el archivo PDF, arrastrelo hasta aqui y sueltelo para subirlo al servidor...'} |
||||||
|
onAppendFM={function (idFile: number): void { |
||||||
|
setIDPDF(idFile) |
||||||
|
updateFile(idFile) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Body> |
||||||
|
</Modal> |
||||||
|
|
||||||
|
<Modal |
||||||
|
show={showModalLog} |
||||||
|
onHide={() => { |
||||||
|
setShowModalLog(false) |
||||||
|
}} |
||||||
|
size={'sm'} |
||||||
|
dialogClassName={'modal-50w'} |
||||||
|
> |
||||||
|
<Modal.Body> |
||||||
|
{HistorialEstatus.length > 0 ? ( |
||||||
|
<Card> |
||||||
|
<table> |
||||||
|
<tr> |
||||||
|
<td>Registrado</td> |
||||||
|
<td>Estatus</td> |
||||||
|
</tr> |
||||||
|
{HistorialEstatus |
||||||
|
? HistorialEstatus.map((item, index) => { |
||||||
|
return ( |
||||||
|
<tr key={item.estatus}> |
||||||
|
<td>{item.fCreacion}</td> |
||||||
|
<td>{item.sEstatus}</td> |
||||||
|
</tr> |
||||||
|
) |
||||||
|
}) |
||||||
|
: ''} |
||||||
|
</table> |
||||||
|
</Card> |
||||||
|
) : ( |
||||||
|
<Alert variant='primary'> |
||||||
|
<Alert.Heading style={{ textAlign: 'center' }}>No hay informacion al respecto</Alert.Heading> |
||||||
|
</Alert> |
||||||
|
)} |
||||||
|
</Modal.Body> |
||||||
|
</Modal> |
||||||
|
|
||||||
|
<Modal |
||||||
|
show={showModalCatalogo} |
||||||
|
onHide={() => { |
||||||
|
setShowModalCatalogo(false) |
||||||
|
}} |
||||||
|
size={'sm'} |
||||||
|
dialogClassName={'modal-50w'} |
||||||
|
> |
||||||
|
<Modal.Body> |
||||||
|
{mCCCEstatus.length > 0 ? ( |
||||||
|
<> |
||||||
|
<Card> |
||||||
|
<Row> |
||||||
|
<Col xs={1}> |
||||||
|
<FloatingLabel controlId='IdEstatus' label='id' className='mb-3'> |
||||||
|
<Form.Control type='text' placeholder='id' value={IDEstatus} disabled={true} /> |
||||||
|
</FloatingLabel> |
||||||
|
</Col> |
||||||
|
<Col xs={10}> |
||||||
|
<FloatingLabel controlId='IdEstatus' label='Estatus' className='mb-3'> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
placeholder='Estatus' |
||||||
|
value={Estatus} |
||||||
|
onChange={(e) => { |
||||||
|
setEstatus(e.target.value) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</FloatingLabel> |
||||||
|
</Col> |
||||||
|
<Col xs={1} style={{ paddingTop: '10px', paddingRight: '50px', cursor: 'pointer' }}> |
||||||
|
<div |
||||||
|
onClick={() => { |
||||||
|
saveEstatus() |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'blue', size: '35px' }}> |
||||||
|
<FiSave /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Card> |
||||||
|
<Card> |
||||||
|
<Row style={{ fontWeight: 'bold' }}> |
||||||
|
<Col xs={1}>id</Col> |
||||||
|
<Col xs={10}>Estatus</Col> |
||||||
|
<Col xs={1}></Col> |
||||||
|
</Row> |
||||||
|
{mCCCEstatus |
||||||
|
? mCCCEstatus |
||||||
|
.filter((item) => { |
||||||
|
return item.id > 1 |
||||||
|
}) |
||||||
|
.map((item, index) => { |
||||||
|
return ( |
||||||
|
<Row |
||||||
|
key={item.estatus} |
||||||
|
onClick={() => { |
||||||
|
setIDEstatus(item.id) |
||||||
|
setEstatus(item.estatus) |
||||||
|
}} |
||||||
|
> |
||||||
|
<Col xs={1}>{item.id}</Col> |
||||||
|
<Col xs={10}>{item.estatus}</Col> |
||||||
|
<Col xs={1}></Col> |
||||||
|
</Row> |
||||||
|
) |
||||||
|
}) |
||||||
|
: ''} |
||||||
|
</Card> |
||||||
|
</> |
||||||
|
) : ( |
||||||
|
<Alert variant='primary'> |
||||||
|
<Alert.Heading style={{ textAlign: 'center' }}>No hay informacion al respecto</Alert.Heading> |
||||||
|
</Alert> |
||||||
|
)} |
||||||
|
</Modal.Body> |
||||||
|
</Modal> |
||||||
|
|
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
time={MsgTime} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,85 @@ |
|||||||
|
import React, { FC, useState } from 'react' |
||||||
|
import { Form } from 'react-bootstrap' |
||||||
|
import { useSelector } from 'react-redux' |
||||||
|
import { RootState } from '../../../../store/store' |
||||||
|
import CuentasComplementariasDS from '../../../../Services/Corresponsalias/Corresponsales.CuentasComplementarias.Services' |
||||||
|
import DTOCuentaComplementariaEstatus from '../../../../DTO/Corresponsales/DTOCuentaComplementariaEstatus' |
||||||
|
import { MsgInformativo } from '../../../Utils/Toast/msgInformativo' |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
IDEstatus: number |
||||||
|
IDCuenta: number |
||||||
|
Enabled: boolean |
||||||
|
} |
||||||
|
|
||||||
|
export const SelectEstatus: FC<IProps> = (props) => { |
||||||
|
const [Depto, setDepto] = useState(() => { |
||||||
|
const stickyValue = window.localStorage.getItem('Departamento') |
||||||
|
return stickyValue !== null ? JSON.parse(stickyValue) : '' |
||||||
|
}) |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msgColor, setMsgColor] = React.useState('primary') |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
const [MsgTime, setMsgTime] = useState(3000) |
||||||
|
const mCCCEstatus = useSelector( |
||||||
|
(state: RootState) => state.CCueCompEstatus.CorresponsalesCuentasComplementariasEstatus |
||||||
|
) |
||||||
|
const [IDEstatus, setIDEstatus] = useState(props.IDEstatus) |
||||||
|
|
||||||
|
const changeStatus = (nuevoEstatus: number) => { |
||||||
|
setIDEstatus(nuevoEstatus) |
||||||
|
const data: DTOCuentaComplementariaEstatus = { |
||||||
|
id: props.IDCuenta, |
||||||
|
estatus: nuevoEstatus, |
||||||
|
} |
||||||
|
CuentasComplementariasDS.ChangeStatus(data) |
||||||
|
.then((response) => { |
||||||
|
setHeader('Confirmacion') |
||||||
|
setMsg('Se ha cambiado el estatus de la cuenta') |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Form.Control |
||||||
|
as='select' |
||||||
|
onChange={(e) => { |
||||||
|
changeStatus(parseInt(e.target.value)) |
||||||
|
}} |
||||||
|
className='form-select form-select-sm' |
||||||
|
style={{ width: '350px' }} |
||||||
|
disabled={Depto !== 'Contabilidad' || props.Enabled} |
||||||
|
value={IDEstatus} |
||||||
|
> |
||||||
|
{mCCCEstatus |
||||||
|
? mCCCEstatus.map((item, index) => { |
||||||
|
return ( |
||||||
|
<option key={item.id} value={item.id}> |
||||||
|
{item.estatus} |
||||||
|
</option> |
||||||
|
) |
||||||
|
}) |
||||||
|
: ''} |
||||||
|
</Form.Control> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
time={MsgTime} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,190 @@ |
|||||||
|
import { FC, useEffect, useState } from 'react' |
||||||
|
import { useDispatch, useSelector } from 'react-redux' |
||||||
|
import { RootState } from '../../../store/store' |
||||||
|
import CGuiasDataService from '../../../Services/Corresponsalias/Corresponsales.Guias.Services' |
||||||
|
import ICorresponsalesGuias from '../../../Interfaces/Corresponsales/ICorresponsalesGuias' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import { BsFillXCircleFill } from 'react-icons/bs' |
||||||
|
import { Alert, Button, Col, Modal, Row } from 'react-bootstrap' |
||||||
|
import { |
||||||
|
deleteCorresponsalesGuias, |
||||||
|
updateCorresponsalesGuias, |
||||||
|
} from '../../../store/features/Corresponsales/CorresponsalesGuiasSlice' |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
IDTrafico: number |
||||||
|
Editable: boolean |
||||||
|
} |
||||||
|
|
||||||
|
export const SelectGuias: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch() |
||||||
|
const [toggleSelect, setToggleSelect] = useState(false) |
||||||
|
const mCGuias = useSelector((state: RootState) => state.CGuias.CorresponsalesGuias) |
||||||
|
const [Guia, setGuia] = useState('') |
||||||
|
const [IDGuia, setIDGuia] = useState(0) |
||||||
|
const [Placeholder, setPlaceholder] = useState('') |
||||||
|
const [DialogTabs, setDialogTabs] = useState(false) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
setPlaceholder('(' + mCGuias.filter((item) => item.id > 0).length + ') Guias') |
||||||
|
}, [mCGuias]) |
||||||
|
|
||||||
|
const loadInfo = (data: ICorresponsalesGuias) => { |
||||||
|
setIDGuia(data.id) |
||||||
|
setGuia(data.guia) |
||||||
|
} |
||||||
|
|
||||||
|
const handleKeyDown = (event: any) => { |
||||||
|
if (event.key === 'Enter') { |
||||||
|
const data: ICorresponsalesGuias = { |
||||||
|
id: IDGuia, |
||||||
|
guia: Guia, |
||||||
|
idTrafico: props.IDTrafico, |
||||||
|
} |
||||||
|
CGuiasDataService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
dispatch(updateCorresponsalesGuias(response.data)) |
||||||
|
setGuia('') |
||||||
|
setToggleSelect(true) |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const deleteItem = () => { |
||||||
|
CGuiasDataService.Delete(IDGuia) |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
setIDGuia(0) |
||||||
|
setGuia('') |
||||||
|
setDialogTabs(false) |
||||||
|
dispatch(deleteCorresponsalesGuias(IDGuia)) |
||||||
|
return |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
return ( |
||||||
|
<div> |
||||||
|
{' '} |
||||||
|
<div className='form-group'> |
||||||
|
<div className='col-sm-12 parent'> |
||||||
|
<div className='input-group'> |
||||||
|
<input type='hidden' className='form-control' name='IDGuia' id='IDGuia' value={IDGuia} /> |
||||||
|
<span className='input-group-addon sorroundImage'> |
||||||
|
<img |
||||||
|
src='http://reportes.gemcousa.com/images/Clean.png' |
||||||
|
width='28' |
||||||
|
height='28' |
||||||
|
style={{ cursor: 'pointer' }} |
||||||
|
alt='' |
||||||
|
onClick={() => { |
||||||
|
setIDGuia(0) |
||||||
|
setGuia('') |
||||||
|
}} |
||||||
|
/> |
||||||
|
</span> |
||||||
|
<input |
||||||
|
type='text' |
||||||
|
className='form-control genericSelect' |
||||||
|
name='Guia' |
||||||
|
id='Guia' |
||||||
|
style={{ height: '30px' }} |
||||||
|
value={Guia} |
||||||
|
placeholder={Placeholder} |
||||||
|
disabled={!props.Editable} |
||||||
|
onChange={(e) => { |
||||||
|
setGuia(e.target.value) |
||||||
|
}} |
||||||
|
onKeyDown={(e) => handleKeyDown(e)} |
||||||
|
/> |
||||||
|
<span className='input-group-addon sorroundImage'> |
||||||
|
<img |
||||||
|
src='http://reportes.gemcousa.com/images/caret.png' |
||||||
|
width='28' |
||||||
|
height='28' |
||||||
|
style={{ cursor: 'pointer' }} |
||||||
|
alt='' |
||||||
|
onClick={() => { |
||||||
|
setToggleSelect(!toggleSelect) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</span> |
||||||
|
<div className='child' style={toggleSelect ? { visibility: 'visible' } : { visibility: 'hidden' }}> |
||||||
|
<ul className='cleanLi'> |
||||||
|
{mCGuias |
||||||
|
? mCGuias |
||||||
|
.map((item, index) => { |
||||||
|
return item.id > 0 ? ( |
||||||
|
<li key={item.id} onClick={() => loadInfo(item)}> |
||||||
|
<span |
||||||
|
onClick={() => { |
||||||
|
setDialogTabs(true) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'red', size: '15px' }}> |
||||||
|
<BsFillXCircleFill /> |
||||||
|
</IconContext.Provider> |
||||||
|
</span> |
||||||
|
<span style={{ paddingLeft: '10px' }}>{item.guia}</span> |
||||||
|
</li> |
||||||
|
) : ( |
||||||
|
'' |
||||||
|
) |
||||||
|
}) |
||||||
|
.reverse() |
||||||
|
: ''} |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<Modal |
||||||
|
show={DialogTabs} |
||||||
|
onHide={() => { |
||||||
|
setDialogTabs(false) |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
<Modal.Body> |
||||||
|
<Alert variant='primary'> |
||||||
|
<b>¿Esta seguro de eliminar?</b> |
||||||
|
<br /> |
||||||
|
<h5> {Guia} </h5> |
||||||
|
</Alert> |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={6} style={{ textAlign: 'left', paddingRight: '100px' }}> |
||||||
|
<Button |
||||||
|
variant='danger' |
||||||
|
onClick={deleteItem} |
||||||
|
size='sm' |
||||||
|
style={{ paddingRight: '20px', paddingLeft: '20px' }} |
||||||
|
> |
||||||
|
Si |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={6} style={{ textAlign: 'right' }}> |
||||||
|
<Button |
||||||
|
variant='secondary' |
||||||
|
onClick={() => { |
||||||
|
setDialogTabs(false) |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Footer> |
||||||
|
</Modal> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,110 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import { MsgInformativo } from '../../../Utils/Toast/msgInformativo' |
||||||
|
import CFac3DataService from '../../../../Services/Corresponsalias/Corresponsales.FacturasTerceros.services' |
||||||
|
import { useDispatch, useSelector } from 'react-redux' |
||||||
|
import ICorresponsalTerceros from '../../../../Interfaces/Corresponsales/ICorresponsalFacturasTerceros' |
||||||
|
import { updateCorresponsalesFacturasTerceros } from '../../../../store/features/Corresponsales/CorresponsalesFacturasTercerosSlice' |
||||||
|
import { Form } from 'react-bootstrap' |
||||||
|
import { RootState } from '../../../../store/store' |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
row: ICorresponsalTerceros |
||||||
|
disabled?: boolean |
||||||
|
mode: number // 1: Number, 2: String
|
||||||
|
} |
||||||
|
|
||||||
|
export const ControlledInput: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch() |
||||||
|
const mProveedores = useSelector((state: RootState) => state.CatProveedores.CatalogoProveedores) |
||||||
|
const [id, setid] = useState(props.row.id) |
||||||
|
const [value, setValue] = useState(props.row.factura) |
||||||
|
const [IDProveedor, setIDProveedor] = useState(props.row.idProveedor) |
||||||
|
const [ClasificacionProveedor, setClasificacionProveedor] = useState(1) |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msgColor, setMsgColor] = React.useState('primary') |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
|
||||||
|
const onChange = (event: any) => { |
||||||
|
setValue(event.target.value) |
||||||
|
} |
||||||
|
|
||||||
|
const handleKeyDown = (event: any) => { |
||||||
|
if (event.key === 'Enter') { |
||||||
|
if (isNaN(event.target.value) && props.mode === 1) { |
||||||
|
alert('Valor no valido!') |
||||||
|
return |
||||||
|
} |
||||||
|
const data: ICorresponsalTerceros = { |
||||||
|
id: id, |
||||||
|
factura: value, |
||||||
|
idTrafico: props.row.idTrafico, |
||||||
|
idProveedor: IDProveedor, |
||||||
|
} |
||||||
|
CFac3DataService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
dispatch(updateCorresponsalesFacturasTerceros(response.data.registro)) |
||||||
|
setHeader('Informativo') |
||||||
|
setMsg('La informacion se guardo exitosamente') |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
console.log('El proveedor es:............................' + JSON.stringify(props.row)) |
||||||
|
}, []) |
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
<input |
||||||
|
value={value} |
||||||
|
onChange={onChange} |
||||||
|
disabled={props.disabled} |
||||||
|
onKeyDown={(e) => handleKeyDown(e)} |
||||||
|
style={{ width: '120px' }} |
||||||
|
/> |
||||||
|
|
||||||
|
<Form.Control |
||||||
|
as='select' |
||||||
|
onChange={(f) => { |
||||||
|
setIDProveedor(parseInt(f.target.value)) |
||||||
|
}} |
||||||
|
value={IDProveedor} |
||||||
|
className='form-select form-select-sm' |
||||||
|
> |
||||||
|
{mProveedores |
||||||
|
? mProveedores |
||||||
|
.filter(function (row) { |
||||||
|
return row.clasificacion === ClasificacionProveedor |
||||||
|
}) |
||||||
|
.map((p) => { |
||||||
|
return ( |
||||||
|
<option value={p.id} key={p.id}> |
||||||
|
{p.nombre} |
||||||
|
</option> |
||||||
|
) |
||||||
|
}) |
||||||
|
: null} |
||||||
|
</Form.Control> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,365 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react'; |
||||||
|
import { Alert, Button, Card, Col, Form, Modal, Row } from 'react-bootstrap'; |
||||||
|
import DataTable from 'react-data-table-component'; |
||||||
|
import { IconContext } from 'react-icons'; |
||||||
|
import { FaEraser, FaTimesCircle } from 'react-icons/fa'; |
||||||
|
import { useDispatch, useSelector } from 'react-redux'; |
||||||
|
import ICorresponsalTerceros from '../../../Interfaces/Corresponsales/ICorresponsalFacturasTerceros'; |
||||||
|
import { RootState } from '../../../store/store'; |
||||||
|
import { MsgInformativo } from '../../Utils/Toast/msgInformativo'; |
||||||
|
import CFac3DataService from '../../../Services/Corresponsalias/Corresponsales.FacturasTerceros.services'; |
||||||
|
import { ControlledInput } from './ControlledInput/ControlledInput'; |
||||||
|
import { |
||||||
|
addCorresponsalesFacturasTerceros, |
||||||
|
deleteCorresponsalesFacturasTerceros, |
||||||
|
} from '../../../store/features/Corresponsales/CorresponsalesFacturasTercerosSlice'; |
||||||
|
import { CatProveedores } from '../CatProveedores/CatProveedores'; |
||||||
|
import { FcManager } from 'react-icons/fc'; |
||||||
|
import { resourceUsage } from 'process'; |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
IDTrafico: number; |
||||||
|
IDCorresponsal: number; |
||||||
|
canDelete: boolean; |
||||||
|
} |
||||||
|
|
||||||
|
export const PagosTerceros: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch(); |
||||||
|
const mCFacturas3 = useSelector( |
||||||
|
(state: RootState) => state.CF3rosData.CorresponsalesFacturasTerceros |
||||||
|
); |
||||||
|
const mProveedores = useSelector( |
||||||
|
(state: RootState) => state.CatProveedores.CatalogoProveedores |
||||||
|
); |
||||||
|
const [IDProveedor, setIDProveedor] = useState(-1); |
||||||
|
const [DTData, setDTData] = useState<ICorresponsalTerceros[]>([]); |
||||||
|
const [ShowModal, setShowModal] = useState(false); |
||||||
|
const [Factura, setFactura] = useState(''); |
||||||
|
const [IDFactura, setIDFactura] = useState(0); |
||||||
|
const [header, setHeader] = useState(''); |
||||||
|
const [msgColor, setMsgColor] = React.useState('primary'); |
||||||
|
const [show, setShowMsg] = useState(false); |
||||||
|
const [msg, setMsg] = useState(''); |
||||||
|
const [MsgTime, setMsgTime] = useState(4000); |
||||||
|
const [DialogTabs, setDialogTabs] = useState(false); |
||||||
|
const [msgDialog, setMsgDialog] = useState(false); |
||||||
|
const [ClasificacionProveedor, setClasificacionProveedor] = useState(1); |
||||||
|
|
||||||
|
const columnsFacturas3 = [ |
||||||
|
{ |
||||||
|
name: 'id', |
||||||
|
width: '10%', |
||||||
|
selector: (row: ICorresponsalTerceros) => row.id, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Factura', |
||||||
|
width: '75%', |
||||||
|
cell: (row: ICorresponsalTerceros) => { |
||||||
|
return <ControlledInput row={row} disabled={false} mode={2} />; |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Elimina', |
||||||
|
cell: (row: ICorresponsalTerceros) => ( |
||||||
|
<div |
||||||
|
style={{ |
||||||
|
textAlign: 'center', |
||||||
|
cursor: 'pointer', |
||||||
|
visibility: props.canDelete ? 'visible' : 'hidden', |
||||||
|
}} |
||||||
|
onClick={() => { |
||||||
|
setIDFactura(row.id); |
||||||
|
setFactura(row.factura); |
||||||
|
setDialogTabs(true); |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'red', size: '25px' }}> |
||||||
|
<FaTimesCircle /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
), |
||||||
|
}, |
||||||
|
]; |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
CFac3DataService.getAll(props.IDTrafico) |
||||||
|
.then((response) => { |
||||||
|
setDTData(response.data); |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error'); |
||||||
|
setMsg('Ocurrio un error: ' + e); |
||||||
|
setShowMsg(true); |
||||||
|
return; |
||||||
|
}); |
||||||
|
mProveedores.length > 0 |
||||||
|
? setIDProveedor(mProveedores[0].id) |
||||||
|
: setIDProveedor(0); |
||||||
|
}, []); |
||||||
|
|
||||||
|
const saveForm = () => { |
||||||
|
if (IDProveedor === 0) { |
||||||
|
setHeader('Error'); |
||||||
|
setMsg('Para poder continuar, por favor, seleccione el proveedor'); |
||||||
|
setShowMsg(true); |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (Factura.length === 0) { |
||||||
|
setHeader('Error'); |
||||||
|
setMsg('Para poder continuar, por favor, proporcione la factura'); |
||||||
|
setShowMsg(true); |
||||||
|
return false; |
||||||
|
} |
||||||
|
const data: ICorresponsalTerceros = { |
||||||
|
id: IDFactura, |
||||||
|
factura: Factura, |
||||||
|
idTrafico: props.IDTrafico, |
||||||
|
idProveedor: IDProveedor, |
||||||
|
}; |
||||||
|
CFac3DataService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
setHeader('Informativo'); |
||||||
|
setMsg(response.data.respuesta); |
||||||
|
setShowMsg(true); |
||||||
|
setDialogTabs(false); |
||||||
|
if (data.id === 0) |
||||||
|
dispatch(addCorresponsalesFacturasTerceros(response.data.registro)); |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((error: any) => { |
||||||
|
if (error.response) { |
||||||
|
setHeader('Error: No se permite duplicidad'); |
||||||
|
setMsgColor('warning'); |
||||||
|
setMsgTime(10000); |
||||||
|
setMsg( |
||||||
|
error.response.data.respuesta + |
||||||
|
' en la factura: ' + |
||||||
|
error.response.data.registro.factura + |
||||||
|
' en el trafico: CG' + |
||||||
|
error.response.data.registro.idTrafico |
||||||
|
); |
||||||
|
setShowMsg(true); |
||||||
|
return; |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
const deleteItem = () => { |
||||||
|
CFac3DataService.Delete(IDFactura) |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
setHeader('Informativo'); |
||||||
|
setMsg(response.data.respuesta); |
||||||
|
setShowMsg(true); |
||||||
|
setDialogTabs(false); |
||||||
|
dispatch(deleteCorresponsalesFacturasTerceros(IDFactura)); |
||||||
|
return; |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error'); |
||||||
|
setMsg('Ocurrio un error: ' + e); |
||||||
|
setShowMsg(true); |
||||||
|
return; |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
const cleanForm = () => { |
||||||
|
setFactura(''); |
||||||
|
setIDFactura(0); |
||||||
|
}; |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Card style={{}}> |
||||||
|
<Card.Body> |
||||||
|
<Card.Subtitle className='mb-2 text-muted'> |
||||||
|
<Row |
||||||
|
style={{ paddingBottom: '5', paddingTop: '15' }} |
||||||
|
className={props.canDelete ? 'visible' : 'invisible heightZero'} |
||||||
|
> |
||||||
|
<Col |
||||||
|
xs={1} |
||||||
|
style={{ |
||||||
|
textAlign: 'right', |
||||||
|
paddingTop: '5px', |
||||||
|
cursor: 'pointer', |
||||||
|
}} |
||||||
|
onClick={() => { |
||||||
|
cleanForm(); |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'orange', size: '25px' }}> |
||||||
|
<FaEraser /> |
||||||
|
</IconContext.Provider> |
||||||
|
</Col> |
||||||
|
<Col> |
||||||
|
<Form.Control |
||||||
|
type='hidden' |
||||||
|
id='IdItem' |
||||||
|
size='sm' |
||||||
|
value={IDFactura} |
||||||
|
placeholder='Contenedor' |
||||||
|
disabled={true} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={2}> |
||||||
|
{/* <Form.Control |
||||||
|
type='text' |
||||||
|
id='FacturaTerceros' |
||||||
|
size='sm' |
||||||
|
value={Factura} |
||||||
|
placeholder='Factura 3ros' |
||||||
|
pattern='[a-zA-Z-0-9 ]*' |
||||||
|
onChange={(e) => setFactura((v) => (e.target.validity.valid ? e.target.value : v))} |
||||||
|
/> */} |
||||||
|
<input |
||||||
|
type='text' |
||||||
|
className='form-control genericSelect' |
||||||
|
name='Factura' |
||||||
|
id='Factura' |
||||||
|
style={{ height: '30px' }} |
||||||
|
value={Factura} |
||||||
|
placeholder='Factura' |
||||||
|
onChange={(e) => { |
||||||
|
setFactura(e.target.value); |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={5}> |
||||||
|
<Form.Control |
||||||
|
as='select' |
||||||
|
id='CmbIDProveedor' |
||||||
|
onChange={(e) => { |
||||||
|
setIDProveedor(parseInt(e.target.value)); |
||||||
|
}} |
||||||
|
className='form-select form-select-sm' |
||||||
|
value={IDProveedor} |
||||||
|
> |
||||||
|
{mProveedores |
||||||
|
? mProveedores |
||||||
|
.filter(function (row) { |
||||||
|
return ( |
||||||
|
row.clasificacion === ClasificacionProveedor || |
||||||
|
row.id === 0 |
||||||
|
); |
||||||
|
}) |
||||||
|
.map((item, index) => { |
||||||
|
return ( |
||||||
|
<option value={item.id} key={item.id}> |
||||||
|
{item.nombre} |
||||||
|
</option> |
||||||
|
); |
||||||
|
}) |
||||||
|
: ''} |
||||||
|
</Form.Control> |
||||||
|
</Col> |
||||||
|
<Col xs={1} style={{ cursor: 'pointer' }}> |
||||||
|
<Button |
||||||
|
variant='primary' |
||||||
|
size='sm' |
||||||
|
onClick={() => { |
||||||
|
setShowModal(true); |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'blue', size: '25px' }}> |
||||||
|
<FcManager /> |
||||||
|
</IconContext.Provider> |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={1}></Col> |
||||||
|
<Col xs={1}> |
||||||
|
<Button |
||||||
|
id='BtnSave' |
||||||
|
variant='primary' |
||||||
|
size='sm' |
||||||
|
onClick={() => { |
||||||
|
saveForm(); |
||||||
|
}} |
||||||
|
> |
||||||
|
Agregar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col> </Col> |
||||||
|
</Row> |
||||||
|
</Card.Subtitle> |
||||||
|
<DataTable |
||||||
|
noHeader |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={columnsFacturas3} |
||||||
|
data={mCFacturas3.filter(function (el) { |
||||||
|
return el.id > 0 && el.idTrafico === props.IDTrafico; |
||||||
|
})} |
||||||
|
/> |
||||||
|
</Card.Body> |
||||||
|
</Card> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
time={MsgTime} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false); |
||||||
|
}} |
||||||
|
/> |
||||||
|
<Modal |
||||||
|
show={DialogTabs} |
||||||
|
onHide={() => { |
||||||
|
setDialogTabs(false); |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
<Modal.Body> |
||||||
|
<Alert variant='primary'> |
||||||
|
<b>¿Esta seguro de eliminar?</b> |
||||||
|
<br /> |
||||||
|
<h5> {Factura} </h5> |
||||||
|
</Alert> |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={6} style={{ textAlign: 'left', paddingRight: '100px' }}> |
||||||
|
<Button |
||||||
|
variant='danger' |
||||||
|
onClick={deleteItem} |
||||||
|
size='sm' |
||||||
|
style={{ paddingRight: '20px', paddingLeft: '20px' }} |
||||||
|
> |
||||||
|
Si |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={6} style={{ textAlign: 'right' }}> |
||||||
|
<Button |
||||||
|
variant='secondary' |
||||||
|
onClick={() => { |
||||||
|
setDialogTabs(false); |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Footer> |
||||||
|
</Modal> |
||||||
|
<Modal |
||||||
|
show={ShowModal} |
||||||
|
onHide={() => { |
||||||
|
setShowModal(false); |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
dialogClassName='modal-50w' |
||||||
|
> |
||||||
|
<Modal.Body> |
||||||
|
<CatProveedores canDelete={true} clasificacion={1} /> |
||||||
|
</Modal.Body> |
||||||
|
</Modal> |
||||||
|
</div> |
||||||
|
); |
||||||
|
}; |
@ -0,0 +1,308 @@ |
|||||||
|
import React, { FC, useEffect, useState } from "react"; |
||||||
|
import { Button, Card, Col, Container, Form, Row } from "react-bootstrap"; |
||||||
|
import * as CurrencyFormat from "react-currency-format"; |
||||||
|
import ICorresponsalPartidas from "../../../../Interfaces/Corresponsales/ICorresponsalPedimentoPartidas"; |
||||||
|
import { MsgInformativo } from "../../../Utils/Toast/msgInformativo"; |
||||||
|
import CPartidasService from "../../../../Services/Corresponsalias/Corresponsales.Trafico.Pedimento.Partidas.Services"; |
||||||
|
import { useDispatch, useSelector } from "react-redux"; |
||||||
|
import { updateCorresponsalesPartidas } from "../../../../store/features/Corresponsales/CorresponsalesPartidasSlice"; |
||||||
|
import { RootState } from "../../../../store/store"; |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
IDTrafico: number; |
||||||
|
IDPartida: number; |
||||||
|
} |
||||||
|
|
||||||
|
export const DialogBox: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch(); |
||||||
|
const mCFacturas = useSelector( |
||||||
|
(state: RootState) => state.CFData.CorresponsalesFacturas |
||||||
|
); |
||||||
|
const mCatProveedores = useSelector( |
||||||
|
(state: RootState) => state.CatProveedores.CatalogoProveedores |
||||||
|
); |
||||||
|
const mCPartidas = useSelector( |
||||||
|
(state: RootState) => state.CPartidas.CorresponsalesPartidas |
||||||
|
); |
||||||
|
const [Factura, setFactura] = useState(""); |
||||||
|
const [IDFactura, setIDFactura] = useState(0); |
||||||
|
const [IDPartida, setIDPartida] = useState(0); |
||||||
|
const [Proveedor, setProveedor] = useState(""); |
||||||
|
const [IDProveedor, setIDProveedor] = useState(0); |
||||||
|
const [DescripcionMaterial, setDescripcionMaterial] = useState(""); |
||||||
|
const [FraccionArancelaria, setFraccionArancelaria] = useState(""); |
||||||
|
const [ValorAduana, setValorAduana] = useState(0); |
||||||
|
const [DTA, setDTA] = useState(0); |
||||||
|
const [IGI, setIGI] = useState(0); |
||||||
|
const [IEPS, setIEPS] = useState(0); |
||||||
|
const [header, setHeader] = useState(""); |
||||||
|
// const [msgColor, setMsgColor] = React.useState('primary')
|
||||||
|
const [show, setShowMsg] = useState(false); |
||||||
|
const [msg, setMsg] = useState(""); |
||||||
|
const msgColor = "primary"; |
||||||
|
|
||||||
|
const saveForm = () => { |
||||||
|
const data: ICorresponsalPartidas = { |
||||||
|
id: IDPartida, |
||||||
|
idTrafico: props.IDTrafico, |
||||||
|
partida: 0, |
||||||
|
idFactura: IDFactura, |
||||||
|
factura: Factura, |
||||||
|
proveedor: Proveedor, |
||||||
|
descripcionMaterial: DescripcionMaterial, |
||||||
|
fraccionArancelaria: FraccionArancelaria, |
||||||
|
valorAduana: ValorAduana, |
||||||
|
dta: DTA, |
||||||
|
igi: IGI, |
||||||
|
ieps: IEPS, |
||||||
|
activo: 1, |
||||||
|
}; |
||||||
|
if (Factura.length < 4) { |
||||||
|
setHeader("Error"); |
||||||
|
setMsg("Proporcione la factura"); |
||||||
|
setShowMsg(true); |
||||||
|
return; |
||||||
|
} |
||||||
|
if (Proveedor.length < 4) { |
||||||
|
setHeader("Error"); |
||||||
|
setMsg("Proporcione el proveedor"); |
||||||
|
setShowMsg(true); |
||||||
|
return; |
||||||
|
} |
||||||
|
if (DescripcionMaterial.length < 4) { |
||||||
|
setHeader("Error"); |
||||||
|
setMsg("Proporcione la descripcion del material"); |
||||||
|
setShowMsg(true); |
||||||
|
return; |
||||||
|
} |
||||||
|
if (FraccionArancelaria.length < 4) { |
||||||
|
setHeader("Error"); |
||||||
|
setMsg("Proporcione la fraccion arancelaria"); |
||||||
|
setShowMsg(true); |
||||||
|
return; |
||||||
|
} |
||||||
|
if (ValorAduana === 0) { |
||||||
|
setHeader("Error"); |
||||||
|
setMsg("Proporcione el valor aduana"); |
||||||
|
setShowMsg(true); |
||||||
|
return; |
||||||
|
} |
||||||
|
console.log(JSON.stringify(data)); |
||||||
|
CPartidasService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
dispatch(updateCorresponsalesPartidas(response.data)); |
||||||
|
setHeader("Informativo"); |
||||||
|
setMsg("El registro se guardado exitosamente!"); |
||||||
|
setShowMsg(true); |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader("Error"); |
||||||
|
setMsg("Ocurrio un error: " + e); |
||||||
|
setShowMsg(true); |
||||||
|
return; |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
const dataFactura = mCFacturas.filter((item) => item.id === IDFactura); |
||||||
|
setFactura(dataFactura[0].factura); |
||||||
|
setIDProveedor(dataFactura[0].proveedor); |
||||||
|
const dataProveedor = mCatProveedores.filter( |
||||||
|
(item) => item.id === dataFactura[0].proveedor |
||||||
|
); |
||||||
|
setProveedor(dataProveedor[0].nombre); |
||||||
|
}, [IDFactura, mCFacturas, mCatProveedores]); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
const data = mCPartidas.filter((item) => item.id === props.IDPartida); |
||||||
|
if (data[0]) { |
||||||
|
setIDPartida(data[0].id); |
||||||
|
setIDFactura(data[0].idFactura); |
||||||
|
setFactura(data[0].factura); |
||||||
|
setDescripcionMaterial(data[0].descripcionMaterial); |
||||||
|
setProveedor(data[0].proveedor); |
||||||
|
setDTA(data[0].dta); |
||||||
|
setIGI(data[0].igi); |
||||||
|
setIEPS(data[0].ieps); |
||||||
|
setFraccionArancelaria(data[0].fraccionArancelaria); |
||||||
|
setValorAduana(data[0].valorAduana); |
||||||
|
} |
||||||
|
}, [props.IDPartida, mCPartidas]); |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Card |
||||||
|
style={{ |
||||||
|
backgroundColor: "#F1F9FE", |
||||||
|
paddingLeft: "10px", |
||||||
|
paddingRight: "10px", |
||||||
|
paddingTop: "5px", |
||||||
|
paddingBottom: "5px", |
||||||
|
}} |
||||||
|
> |
||||||
|
<Container fluid="md"> |
||||||
|
<Row style={{ paddingTop: "15px" }}> |
||||||
|
<Col xs={2}>Factura</Col> |
||||||
|
<Col xs={3}> |
||||||
|
{/* <Form.Control |
||||||
|
type='text' |
||||||
|
id='Factura' |
||||||
|
size='sm' |
||||||
|
value={Factura} |
||||||
|
onChange={(e) => { |
||||||
|
setFactura(e.target.value) |
||||||
|
}} |
||||||
|
/> */} |
||||||
|
<Form.Control |
||||||
|
id="CmbFacturas" |
||||||
|
as="select" |
||||||
|
onChange={(e) => { |
||||||
|
setIDFactura(parseInt(e.target.value)); |
||||||
|
}} |
||||||
|
value={IDFactura} |
||||||
|
className="form-select form-select-sm" |
||||||
|
> |
||||||
|
{mCFacturas |
||||||
|
? mCFacturas.map((item, index) => { |
||||||
|
return item.idTrafico === props.IDTrafico ? ( |
||||||
|
<option value={item.id}>{item.factura}</option> |
||||||
|
) : ( |
||||||
|
<option value="0">-Seleccione-</option> |
||||||
|
); |
||||||
|
}) |
||||||
|
: ""} |
||||||
|
</Form.Control> |
||||||
|
</Col> |
||||||
|
<Col xs={5}></Col> |
||||||
|
<Col> |
||||||
|
<Button |
||||||
|
id="BtnSavePartida" |
||||||
|
variant="primary" |
||||||
|
onClick={() => { |
||||||
|
saveForm(); |
||||||
|
}} |
||||||
|
> |
||||||
|
Guardar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row style={{ paddingTop: "15px" }}> |
||||||
|
<Col xs={2}>Proveedor</Col> |
||||||
|
<Col xs={10}> |
||||||
|
<Form.Control |
||||||
|
type="text" |
||||||
|
id="Proveedor" |
||||||
|
size="sm" |
||||||
|
value={Proveedor} |
||||||
|
onChange={(e) => { |
||||||
|
setProveedor(e.target.value); |
||||||
|
}} |
||||||
|
disabled={true} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row style={{ paddingTop: "15px" }}> |
||||||
|
<Col xs={2}>Descripcion del material</Col> |
||||||
|
<Col> |
||||||
|
<Form.Control |
||||||
|
rows={4} |
||||||
|
as="textarea" |
||||||
|
id="DescripcionMaterial" |
||||||
|
value={DescripcionMaterial} |
||||||
|
size="sm" |
||||||
|
onChange={(e) => { |
||||||
|
setDescripcionMaterial(e.target.value); |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row style={{ paddingTop: "15px" }}> |
||||||
|
<Col xs={3}>Fraccion arancelaria</Col> |
||||||
|
<Col xs={3}> |
||||||
|
<Form.Control |
||||||
|
type="text" |
||||||
|
id="FraccionArancelaria" |
||||||
|
size="sm" |
||||||
|
value={FraccionArancelaria} |
||||||
|
onChange={(e) => { |
||||||
|
setFraccionArancelaria(e.target.value); |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={2}>Valor aduana</Col> |
||||||
|
<Col xs={3}> |
||||||
|
<CurrencyFormat |
||||||
|
id="ValorAduana" |
||||||
|
value={ValorAduana} |
||||||
|
thousandSeparator={true} |
||||||
|
placeholder="ValorAduana" |
||||||
|
onValueChange={(values: any) => { |
||||||
|
const { value } = values; |
||||||
|
setValorAduana(value); |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row style={{ paddingTop: "15px" }}> |
||||||
|
<Col xs={1} style={{ textAlign: "right" }}> |
||||||
|
DTA |
||||||
|
</Col> |
||||||
|
<Col xs={2}> |
||||||
|
<CurrencyFormat |
||||||
|
id="CDTA" |
||||||
|
placeholder="DTA" |
||||||
|
value={DTA} |
||||||
|
thousandSeparator={true} |
||||||
|
onValueChange={(values: any) => { |
||||||
|
const { value } = values; |
||||||
|
setDTA(value.length === 0 ? 0 : value); |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={1}> </Col> |
||||||
|
<Col xs={1} style={{ textAlign: "right" }}> |
||||||
|
IGI |
||||||
|
</Col> |
||||||
|
<Col xs={2}> |
||||||
|
<CurrencyFormat |
||||||
|
id="CIGI" |
||||||
|
value={IGI} |
||||||
|
thousandSeparator={true} |
||||||
|
placeholder="IGI" |
||||||
|
onValueChange={(values: any) => { |
||||||
|
const { value } = values; |
||||||
|
setIGI(value); |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={1}> </Col> |
||||||
|
<Col xs={1} style={{ textAlign: "right" }}> |
||||||
|
IEPS |
||||||
|
</Col> |
||||||
|
<Col xs={2}> |
||||||
|
<CurrencyFormat |
||||||
|
id="CIEPS" |
||||||
|
value={IEPS} |
||||||
|
thousandSeparator={true} |
||||||
|
placeholder="IEPS" |
||||||
|
onValueChange={(values: any) => { |
||||||
|
const { value } = values; |
||||||
|
setIEPS(value); |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Container> |
||||||
|
</Card> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false); |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
); |
||||||
|
}; |
@ -0,0 +1,270 @@ |
|||||||
|
import React, { FC, useState } from "react"; |
||||||
|
import { Alert, Button, Card, Col, Modal, Row } from "react-bootstrap"; |
||||||
|
import ICorresponsalPartidas from "../../../Interfaces/Corresponsales/ICorresponsalPedimentoPartidas"; |
||||||
|
import { MsgInformativo } from "../../Utils/Toast/msgInformativo"; |
||||||
|
import CPartidasService from "../../../Services/Corresponsalias/Corresponsales.Trafico.Pedimento.Partidas.Services"; |
||||||
|
import { useDispatch, useSelector } from "react-redux"; |
||||||
|
import DataTable from "react-data-table-component"; |
||||||
|
import { IconContext } from "react-icons"; |
||||||
|
import { BsFillPencilFill, BsFillTrashFill } from "react-icons/bs"; |
||||||
|
import { RootState } from "../../../store/store"; |
||||||
|
import { DialogBox } from "./Dialog/DialogBox"; |
||||||
|
import { deleteCorresponsalesPartidas } from "../../../store/features/Corresponsales/CorresponsalesPartidasSlice"; |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
IDTrafico: number; |
||||||
|
canEdit: boolean; |
||||||
|
} |
||||||
|
|
||||||
|
export const Partidas: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch(); |
||||||
|
const [Depto, setDepto] = useState(() => { |
||||||
|
const stickyValue = window.localStorage.getItem("Departamento"); |
||||||
|
return stickyValue !== null ? JSON.parse(stickyValue) : ""; |
||||||
|
}); |
||||||
|
const [ShowModal, setShowModal] = useState(false); |
||||||
|
const [MsgDialogDelete, setMsgDialogDelete] = useState(false); |
||||||
|
const [IDPartida, setIDPartida] = useState(0); |
||||||
|
const [Factura, setFactura] = useState(""); |
||||||
|
const [Descripcion, setDescripcion] = useState(""); |
||||||
|
const [header, setHeader] = useState(""); |
||||||
|
const [show, setShowMsg] = useState(false); |
||||||
|
const [msg, setMsg] = useState(""); |
||||||
|
// const [Info, setInfo] = useState<ICorresponsalPartidas>()
|
||||||
|
const mCPartidas = useSelector( |
||||||
|
(state: RootState) => state.CPartidas.CorresponsalesPartidas |
||||||
|
); |
||||||
|
const msgColor = "primary"; |
||||||
|
const dataColPartidas = [ |
||||||
|
{ |
||||||
|
name: "Partida", |
||||||
|
width: "90px", |
||||||
|
selector: (row: ICorresponsalPartidas) => row.partida, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "Factura", |
||||||
|
width: "100px", |
||||||
|
selector: (row: ICorresponsalPartidas) => row.factura, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "Proveedor", |
||||||
|
center: true, |
||||||
|
width: "450px", |
||||||
|
selector: (row: ICorresponsalPartidas) => row.proveedor, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "Descripcion de material", |
||||||
|
center: true, |
||||||
|
width: "450px", |
||||||
|
selector: (row: ICorresponsalPartidas) => row.descripcionMaterial, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "Frac arancelaria", |
||||||
|
center: true, |
||||||
|
width: "120px", |
||||||
|
selector: (row: ICorresponsalPartidas) => row.fraccionArancelaria, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "Val aduana", |
||||||
|
center: true, |
||||||
|
width: "100px", |
||||||
|
selector: (row: ICorresponsalPartidas) => row.valorAduana, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "DTA", |
||||||
|
center: true, |
||||||
|
width: "70px", |
||||||
|
selector: (row: ICorresponsalPartidas) => row.dta, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "IGI", |
||||||
|
center: true, |
||||||
|
width: "70px", |
||||||
|
selector: (row: ICorresponsalPartidas) => row.igi, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "IEPS", |
||||||
|
center: true, |
||||||
|
width: "70px", |
||||||
|
selector: (row: ICorresponsalPartidas) => row.ieps, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "", |
||||||
|
width: "130px", |
||||||
|
cell: (row: ICorresponsalPartidas) => ( |
||||||
|
<Row> |
||||||
|
<Col> |
||||||
|
<div |
||||||
|
style={{ |
||||||
|
textAlign: "center", |
||||||
|
cursor: "pointer", |
||||||
|
visibility: props.canEdit ? "visible" : "hidden", |
||||||
|
}} |
||||||
|
onClick={() => { |
||||||
|
loadData(row); |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: "blue", size: "20px" }}> |
||||||
|
<BsFillPencilFill /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
</Col> |
||||||
|
<Col> </Col> |
||||||
|
<Col> |
||||||
|
<div |
||||||
|
style={{ |
||||||
|
textAlign: "center", |
||||||
|
cursor: "pointer", |
||||||
|
visibility: props.canEdit ? "visible" : "hidden", |
||||||
|
}} |
||||||
|
onClick={() => { |
||||||
|
confirmDelete(row); |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: "red", size: "20px" }}> |
||||||
|
<BsFillTrashFill /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
), |
||||||
|
}, |
||||||
|
]; |
||||||
|
|
||||||
|
const loadData = (row: ICorresponsalPartidas) => { |
||||||
|
setIDPartida(row.id); |
||||||
|
setShowModal(true); |
||||||
|
}; |
||||||
|
|
||||||
|
const confirmDelete = (row: ICorresponsalPartidas) => { |
||||||
|
setIDPartida(row.id); |
||||||
|
setFactura(row.factura); |
||||||
|
setDescripcion(row.descripcionMaterial); |
||||||
|
setMsgDialogDelete(true); |
||||||
|
}; |
||||||
|
|
||||||
|
const deleteItem = () => { |
||||||
|
CPartidasService.Delete(IDPartida) |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
dispatch(deleteCorresponsalesPartidas(IDPartida)); |
||||||
|
setMsgDialogDelete(false); |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader("Error"); |
||||||
|
setMsg("Ocurrio un error: " + e); |
||||||
|
setShowMsg(true); |
||||||
|
return; |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Card |
||||||
|
style={{ |
||||||
|
backgroundColor: "#F1F9FE", |
||||||
|
paddingLeft: "10px", |
||||||
|
paddingRight: "10px", |
||||||
|
paddingTop: "5px", |
||||||
|
paddingBottom: "5px", |
||||||
|
}} |
||||||
|
> |
||||||
|
<Card.Title> |
||||||
|
<Row> |
||||||
|
<Col xs={11}> Partidas</Col> |
||||||
|
<Col> |
||||||
|
<Button |
||||||
|
style={{ |
||||||
|
visibility: |
||||||
|
Depto === "Corresponsalias" ? "visible" : "hidden", |
||||||
|
}} |
||||||
|
variant="primary" |
||||||
|
onClick={() => { |
||||||
|
setIDPartida(0); |
||||||
|
setShowModal(true); |
||||||
|
}} |
||||||
|
> |
||||||
|
Agregar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Card.Title> |
||||||
|
<DataTable |
||||||
|
defaultSortFieldId={"id"} |
||||||
|
defaultSortAsc={true} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={dataColPartidas} |
||||||
|
data={mCPartidas.filter((a) => { |
||||||
|
if (a.idTrafico === props.IDTrafico) { |
||||||
|
return a; |
||||||
|
} |
||||||
|
})} |
||||||
|
/> |
||||||
|
</Card> |
||||||
|
<Modal |
||||||
|
show={ShowModal} |
||||||
|
onHide={() => { |
||||||
|
setShowModal(false); |
||||||
|
}} |
||||||
|
size={"sm"} |
||||||
|
dialogClassName={"modal-50w"} |
||||||
|
> |
||||||
|
<Modal.Body> |
||||||
|
<div style={{ height: "400px", overflow: "scroll" }}> |
||||||
|
<DialogBox IDTrafico={props.IDTrafico} IDPartida={IDPartida} /> |
||||||
|
</div> |
||||||
|
</Modal.Body> |
||||||
|
</Modal> |
||||||
|
<Modal |
||||||
|
show={MsgDialogDelete} |
||||||
|
onHide={() => setMsgDialogDelete(false)} |
||||||
|
size="lg" |
||||||
|
> |
||||||
|
<Modal.Body> |
||||||
|
<Alert variant="primary"> |
||||||
|
<h5> |
||||||
|
Favor de confirmar |
||||||
|
<br /> |
||||||
|
<br /> |
||||||
|
¿Esta seguro de eliminar la factura: {Factura} : {Descripcion}? |
||||||
|
</h5> |
||||||
|
</Alert> |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={1}> |
||||||
|
<Button |
||||||
|
variant="secondary" |
||||||
|
onClick={() => setMsgDialogDelete(false)} |
||||||
|
size="sm" |
||||||
|
> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={5} style={{ paddingLeft: "550px", paddingRight: "0px" }}> |
||||||
|
|
||||||
|
</Col> |
||||||
|
<Col xs={1}> |
||||||
|
<Button variant="danger" onClick={() => deleteItem()} size="sm"> |
||||||
|
Eliminar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Footer> |
||||||
|
</Modal> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false); |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
); |
||||||
|
}; |
@ -0,0 +1,148 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react'; |
||||||
|
import { MsgInformativo } from '../../../Utils/Toast/msgInformativo'; |
||||||
|
import { useDispatch, useSelector } from 'react-redux'; |
||||||
|
import { updateCorresponsalesFacturas } from '../../../../store/features/Corresponsales/CorresponsalesFacturasSlice'; |
||||||
|
import ICorresponsalFacturas from '../../../../Interfaces/Corresponsales/ICorresponsalFacturas'; |
||||||
|
import CorFacDataService from '../../../../Services/Corresponsalias/Corresponsales.Facturas.Services'; |
||||||
|
import { RootState } from '../../../../store/store'; |
||||||
|
import { Form } from 'react-bootstrap'; |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
record: ICorresponsalFacturas; |
||||||
|
disabled?: boolean; |
||||||
|
mode: number; // 1: Number, 2: String
|
||||||
|
} |
||||||
|
|
||||||
|
export const ControlledInput: FC<IProps> = (props) => { |
||||||
|
const dispatch = useDispatch(); |
||||||
|
const mProveedores = useSelector( |
||||||
|
(state: RootState) => state.CatProveedores.CatalogoProveedores |
||||||
|
); |
||||||
|
const [id, setid] = useState(props.record.id); |
||||||
|
const [value, setValue] = useState(props.record.factura); |
||||||
|
const [IDProveedor, setIDProveedor] = useState(props.record.proveedor); |
||||||
|
const [ValorFacturaDls, setValorFacturaDls] = useState( |
||||||
|
props.record.valorFacturaDls |
||||||
|
); |
||||||
|
const [Pedido, setPedido] = useState(props.record.pedido); |
||||||
|
const [header, setHeader] = useState(''); |
||||||
|
const [msgColor, setMsgColor] = React.useState('primary'); |
||||||
|
const [show, setShowMsg] = useState(false); |
||||||
|
const [msg, setMsg] = useState(''); |
||||||
|
const [ClasificacionProveedor, setClasificacionProveedor] = useState(2); |
||||||
|
|
||||||
|
const onChangeFac = (event: any) => { |
||||||
|
setValue(event.target.value); |
||||||
|
}; |
||||||
|
|
||||||
|
const onChangeDls = (event: any) => { |
||||||
|
setValorFacturaDls(event.target.value); |
||||||
|
}; |
||||||
|
|
||||||
|
const onChangePed = (event: any) => { |
||||||
|
setPedido(event.target.value); |
||||||
|
}; |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
console.log(mProveedores); |
||||||
|
}, [mProveedores]); |
||||||
|
|
||||||
|
const handleKeyDown = (event: any, mode: number) => { |
||||||
|
if (event.key === 'Enter') { |
||||||
|
if (isNaN(event.target.value) && mode === 1) { |
||||||
|
alert('Valor no valido!'); |
||||||
|
return; |
||||||
|
} |
||||||
|
const data: ICorresponsalFacturas = { |
||||||
|
id: id, |
||||||
|
factura: value, |
||||||
|
idTrafico: props.record.idTrafico, |
||||||
|
valorFacturaDls: ValorFacturaDls, |
||||||
|
proveedor: IDProveedor, |
||||||
|
corresponsal: props.record.corresponsal, |
||||||
|
pedido: Pedido, |
||||||
|
code: 0, |
||||||
|
folioGEMCO: '', |
||||||
|
}; |
||||||
|
CorFacDataService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
if (response.status == 200) { |
||||||
|
dispatch(updateCorresponsalesFacturas(response.data)); |
||||||
|
setHeader('Informativo'); |
||||||
|
setMsg('La informacion se guardo exitosamente'); |
||||||
|
setShowMsg(true); |
||||||
|
return; |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error'); |
||||||
|
setMsg('Ocurrio un error: ' + e); |
||||||
|
setShowMsg(true); |
||||||
|
return; |
||||||
|
}); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
function changeValue(val: number) { |
||||||
|
setIDProveedor(val); |
||||||
|
} |
||||||
|
return ( |
||||||
|
<> |
||||||
|
<input |
||||||
|
value={value} |
||||||
|
onChange={onChangeFac} |
||||||
|
disabled={false} |
||||||
|
onKeyDown={(e) => handleKeyDown(e, 2)} |
||||||
|
style={{ width: '25%', textAlign: 'right' }} |
||||||
|
/> |
||||||
|
|
||||||
|
<input |
||||||
|
value={ValorFacturaDls} |
||||||
|
onChange={onChangeDls} |
||||||
|
disabled={false} |
||||||
|
onKeyDown={(e) => handleKeyDown(e, 1)} |
||||||
|
style={{ width: '20%', textAlign: 'right' }} |
||||||
|
/> |
||||||
|
|
||||||
|
<input |
||||||
|
value={Pedido} |
||||||
|
onChange={onChangePed} |
||||||
|
disabled={false} |
||||||
|
onKeyDown={(e) => handleKeyDown(e, 2)} |
||||||
|
style={{ width: '20%', textAlign: 'right' }} |
||||||
|
/> |
||||||
|
|
||||||
|
<Form.Control |
||||||
|
as='select' |
||||||
|
onChange={(f) => { |
||||||
|
changeValue(parseInt(f.target.value)); |
||||||
|
}} |
||||||
|
value={IDProveedor} |
||||||
|
className='form-select form-select-sm' |
||||||
|
> |
||||||
|
{mProveedores |
||||||
|
? mProveedores |
||||||
|
.filter(function (row) { |
||||||
|
return row.clasificacion === ClasificacionProveedor; |
||||||
|
}) |
||||||
|
.map((p) => { |
||||||
|
return ( |
||||||
|
<option value={p.id} key={p.id}> |
||||||
|
{p.nombre} |
||||||
|
</option> |
||||||
|
); |
||||||
|
}) |
||||||
|
: null} |
||||||
|
</Form.Control> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false); |
||||||
|
}} |
||||||
|
/> |
||||||
|
</> |
||||||
|
); |
||||||
|
}; |
@ -0,0 +1,426 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react'; |
||||||
|
import { Alert, Button, Card, Col, Form, Modal, Row } from 'react-bootstrap'; |
||||||
|
import { IconContext } from 'react-icons'; |
||||||
|
import 'react-flexy-table/dist/index.css'; |
||||||
|
import FacDataService from '../../../Services/Corresponsalias/Corresponsales.Facturas.Services'; |
||||||
|
import { RootState } from '../../../store/store'; |
||||||
|
import { useDispatch, useSelector } from 'react-redux'; |
||||||
|
import { FcManager } from 'react-icons/fc'; |
||||||
|
import ICorresponsalFacturas from '../../../Interfaces/Corresponsales/ICorresponsalFacturas'; |
||||||
|
import { |
||||||
|
addCorresponsalesFacturas, |
||||||
|
deleteCorresponsalesFacturas, |
||||||
|
populateCorresponsalesFacturas, |
||||||
|
} from '../../../store/features/Corresponsales/CorresponsalesFacturasSlice'; |
||||||
|
import '../../../css/react-flexy-table.css'; |
||||||
|
import { MsgInformativo } from '../../Utils/Toast/msgInformativo'; |
||||||
|
import * as CurrencyFormat from 'react-currency-format'; |
||||||
|
import { CatProveedores } from '../CatProveedores/CatProveedores'; |
||||||
|
import { FaEraser, FaTimesCircle } from 'react-icons/fa'; |
||||||
|
import DataTable from 'react-data-table-component'; |
||||||
|
import { ControlledInput } from './ControlledInput/ControlledInput'; |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
IDTrafico: number; |
||||||
|
IDCorresponsal: number; |
||||||
|
canDelete: boolean; |
||||||
|
} |
||||||
|
|
||||||
|
export const ProveedorFactura: FC<IProps> = (props) => { |
||||||
|
const mCFacturas = useSelector( |
||||||
|
(state: RootState) => state.CFData.CorresponsalesFacturas |
||||||
|
); |
||||||
|
const mProveedores = useSelector( |
||||||
|
(state: RootState) => state.CatProveedores.CatalogoProveedores |
||||||
|
); |
||||||
|
const dispatch = useDispatch(); |
||||||
|
const [ShowModal, setShowModal] = useState(false); |
||||||
|
const [IDFactura, setIDFactura] = useState(0); |
||||||
|
const [Factura, setFactura] = useState(''); |
||||||
|
const [ValorFacturaDls, setValorFacturaDls] = useState<number>(0); |
||||||
|
const [Pedido, setPedido] = useState(''); |
||||||
|
const [header, setHeader] = useState(''); |
||||||
|
const [show, setShowMsg] = useState(false); |
||||||
|
const [msg, setMsg] = useState(''); |
||||||
|
const [DialogTabs, setDialogTabs] = useState(false); |
||||||
|
const [IDProveedor, setIDProveedor] = useState(0); |
||||||
|
const MsgTime = 2000; |
||||||
|
const msgColor = 'primary'; |
||||||
|
const ClasificacionProveedor = 2; |
||||||
|
|
||||||
|
const TblHeader: React.FC = () => ( |
||||||
|
<table> |
||||||
|
<tr |
||||||
|
style={{ |
||||||
|
fontSize: '15px', |
||||||
|
fontWeight: 'bold', |
||||||
|
backgroundColor: '#FFFFFF', |
||||||
|
}} |
||||||
|
> |
||||||
|
<td width='140px' style={{ textAlign: 'center' }}> |
||||||
|
Factura |
||||||
|
</td> |
||||||
|
<td width='120px' style={{ textAlign: 'center' }}> |
||||||
|
Valor Dls |
||||||
|
</td> |
||||||
|
<td width='120px' style={{ textAlign: 'center' }}> |
||||||
|
Pedido |
||||||
|
</td> |
||||||
|
<td width='560px' style={{ textAlign: 'center' }}> |
||||||
|
Proveedor |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
); |
||||||
|
|
||||||
|
const columnsFacturas = [ |
||||||
|
{ |
||||||
|
name: 'id', |
||||||
|
width: '10%', |
||||||
|
selector: (row: ICorresponsalFacturas) => row.id, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: <TblHeader />, |
||||||
|
width: '75%', |
||||||
|
cell: (row: ICorresponsalFacturas) => { |
||||||
|
return <ControlledInput record={row} disabled={false} mode={2} />; |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Elimina', |
||||||
|
cell: (row: ICorresponsalFacturas) => ( |
||||||
|
<div |
||||||
|
style={{ |
||||||
|
textAlign: 'center', |
||||||
|
cursor: 'pointer', |
||||||
|
visibility: props.canDelete ? 'visible' : 'hidden', |
||||||
|
}} |
||||||
|
onClick={() => { |
||||||
|
setIDFactura(row.id); |
||||||
|
setFactura(row.factura); |
||||||
|
setDialogTabs(true); |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'red', size: '25px' }}> |
||||||
|
<FaTimesCircle /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
), |
||||||
|
}, |
||||||
|
]; |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
FacDataService.getAll(props.IDTrafico) |
||||||
|
.then((response) => { |
||||||
|
dispatch(populateCorresponsalesFacturas(response.data)); |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error'); |
||||||
|
setMsg('Ocurrio un error: ' + e); |
||||||
|
setShowMsg(true); |
||||||
|
return; |
||||||
|
}); |
||||||
|
}, [props.IDTrafico, dispatch]); |
||||||
|
|
||||||
|
const cleanForm = () => { |
||||||
|
setFactura(''); |
||||||
|
setIDFactura(0); |
||||||
|
setIDProveedor(0); |
||||||
|
setValorFacturaDls(0); |
||||||
|
}; |
||||||
|
|
||||||
|
const saveForm = () => { |
||||||
|
if (Factura.length <= 3) { |
||||||
|
setHeader('Error'); |
||||||
|
setMsg('Proporcione la factura para poder continuar'); |
||||||
|
setShowMsg(true); |
||||||
|
setDialogTabs(false); |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (ValorFacturaDls === 0) { |
||||||
|
setHeader('Error'); |
||||||
|
setMsg('Proporcione el valor en dlls de la factura para poder continuar'); |
||||||
|
setShowMsg(true); |
||||||
|
setDialogTabs(false); |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (IDProveedor === 0) { |
||||||
|
setHeader('Error'); |
||||||
|
setMsg('Seleccione un proveedor para poder continuar'); |
||||||
|
setShowMsg(true); |
||||||
|
setDialogTabs(false); |
||||||
|
return false; |
||||||
|
} |
||||||
|
const data: ICorresponsalFacturas = { |
||||||
|
id: 0, |
||||||
|
factura: Factura, |
||||||
|
idTrafico: props.IDTrafico, |
||||||
|
valorFacturaDls: ValorFacturaDls, |
||||||
|
proveedor: IDProveedor, |
||||||
|
corresponsal: props.IDCorresponsal, |
||||||
|
pedido: Pedido, |
||||||
|
code: 0, |
||||||
|
folioGEMCO: '', |
||||||
|
}; |
||||||
|
FacDataService.Append(data) |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
setHeader('Informativo'); |
||||||
|
const respuesta: ICorresponsalFacturas = response.data; |
||||||
|
console.log(respuesta); |
||||||
|
if (respuesta.code && typeof respuesta.code === 'number') { |
||||||
|
const result = respuesta.code; |
||||||
|
if (result === 409) |
||||||
|
setMsg( |
||||||
|
`La factura [${response.data.factura}] de ese proveedor ya se han registrado previamente en el año en curso, lo encuentra en el folio [${response.data.folioGEMCO}]` |
||||||
|
); |
||||||
|
else { |
||||||
|
setMsg('La factura se agrego exitosamente '); |
||||||
|
if (data.id === 0) |
||||||
|
dispatch(addCorresponsalesFacturas(response.data)); |
||||||
|
} |
||||||
|
} |
||||||
|
setShowMsg(true); |
||||||
|
setDialogTabs(false); |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error'); |
||||||
|
setMsg('Ocurrio un error: ' + e); |
||||||
|
setShowMsg(true); |
||||||
|
return; |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
const deleteItem = () => { |
||||||
|
FacDataService.Delete(IDFactura) |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
setHeader('Informativo'); |
||||||
|
setMsg('La factura se ha eliminado'); |
||||||
|
setShowMsg(true); |
||||||
|
setDialogTabs(false); |
||||||
|
dispatch(deleteCorresponsalesFacturas(IDFactura)); |
||||||
|
return; |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error'); |
||||||
|
setMsg('Ocurrio un error: ' + e); |
||||||
|
setShowMsg(true); |
||||||
|
return; |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Card style={{}}> |
||||||
|
<Card.Body> |
||||||
|
<Card.Subtitle className='mb-2 text-muted'> |
||||||
|
<Row |
||||||
|
style={{ paddingBottom: '5', paddingTop: '15' }} |
||||||
|
className={props.canDelete ? 'visible' : 'invisible heightZero'} |
||||||
|
> |
||||||
|
<Col |
||||||
|
xs={1} |
||||||
|
style={{ |
||||||
|
textAlign: 'right', |
||||||
|
paddingTop: '5px', |
||||||
|
cursor: 'pointer', |
||||||
|
}} |
||||||
|
onClick={() => { |
||||||
|
cleanForm(); |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'orange', size: '25px' }}> |
||||||
|
<FaEraser /> |
||||||
|
</IconContext.Provider> |
||||||
|
</Col> |
||||||
|
<Col xs='1'> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
id='Factura' |
||||||
|
size='sm' |
||||||
|
value={Factura} |
||||||
|
placeholder='Factura' |
||||||
|
pattern='[a-zA-Z-0-9 ]*' |
||||||
|
onChange={(e) => |
||||||
|
setFactura((v) => |
||||||
|
e.target.validity.valid ? e.target.value : v |
||||||
|
) |
||||||
|
} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs='1'> |
||||||
|
<CurrencyFormat |
||||||
|
id='ValorFacturaDls' |
||||||
|
value={ValorFacturaDls} |
||||||
|
prefix={'$'} |
||||||
|
displayType={'input'} |
||||||
|
thousandSeparator={true} |
||||||
|
onValueChange={(values: any) => { |
||||||
|
const { value } = values; |
||||||
|
setValorFacturaDls(value); |
||||||
|
}} |
||||||
|
style={{ |
||||||
|
fontSize: '18px', |
||||||
|
backgroundColor: '#F5FFED', |
||||||
|
border: '2px solid #25D05B', |
||||||
|
width: '100px', |
||||||
|
textAlign: 'right', |
||||||
|
borderRadius: '10px', |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={1}> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
id='Pedido' |
||||||
|
size='sm' |
||||||
|
value={Pedido} |
||||||
|
placeholder='Pedido' |
||||||
|
onChange={(e) => setPedido(e.target.value)} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col xs={5}> |
||||||
|
<Form.Control |
||||||
|
id='IDProveedor' |
||||||
|
as='select' |
||||||
|
onChange={(e) => { |
||||||
|
setIDProveedor(parseInt(e.target.value)); |
||||||
|
}} |
||||||
|
className='form-select form-select-sm' |
||||||
|
value={IDProveedor} |
||||||
|
> |
||||||
|
<option>-Seleccione-</option> |
||||||
|
{mProveedores |
||||||
|
? mProveedores |
||||||
|
.filter(function (row) { |
||||||
|
return row.clasificacion === ClasificacionProveedor; |
||||||
|
}) |
||||||
|
.map((item, index) => { |
||||||
|
return ( |
||||||
|
<option value={item.id} key={item.id}> |
||||||
|
{item.nombre} |
||||||
|
</option> |
||||||
|
); |
||||||
|
}) |
||||||
|
: ''} |
||||||
|
</Form.Control> |
||||||
|
</Col> |
||||||
|
<Col xs={1} style={{ cursor: 'pointer' }}> |
||||||
|
<Button |
||||||
|
variant='primary' |
||||||
|
size='sm' |
||||||
|
onClick={() => { |
||||||
|
setShowModal(true); |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'blue', size: '25px' }}> |
||||||
|
<FcManager /> |
||||||
|
</IconContext.Provider> |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={1}></Col> |
||||||
|
<Col xs={1}> |
||||||
|
<Button |
||||||
|
id='BtnSave' |
||||||
|
variant='primary' |
||||||
|
size='sm' |
||||||
|
onClick={() => { |
||||||
|
saveForm(); |
||||||
|
}} |
||||||
|
> |
||||||
|
Agregar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col> </Col> |
||||||
|
</Row> |
||||||
|
</Card.Subtitle> |
||||||
|
<DataTable |
||||||
|
/* noHeader */ |
||||||
|
fixedHeader={true} |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
fixedHeaderScrollHeight='400px' |
||||||
|
persistTableHead |
||||||
|
striped |
||||||
|
dense |
||||||
|
paginationPerPage={7} |
||||||
|
paginationRowsPerPageOptions={[7, 10, 14, 20, 21]} |
||||||
|
responsive |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={columnsFacturas} |
||||||
|
data={mCFacturas.filter(function (el) { |
||||||
|
return el.id > 0; |
||||||
|
})} |
||||||
|
/> |
||||||
|
</Card.Body> |
||||||
|
</Card> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
time={MsgTime} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false); |
||||||
|
}} |
||||||
|
/> |
||||||
|
<Modal |
||||||
|
show={DialogTabs} |
||||||
|
onHide={() => { |
||||||
|
setDialogTabs(false); |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
<Modal.Body> |
||||||
|
<Alert variant='primary'> |
||||||
|
<b>¿Esta seguro de eliminar?</b> |
||||||
|
<br /> |
||||||
|
<h5> {Factura} </h5> |
||||||
|
</Alert> |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={6} style={{ textAlign: 'left', paddingRight: '100px' }}> |
||||||
|
<Button |
||||||
|
variant='danger' |
||||||
|
onClick={deleteItem} |
||||||
|
size='sm' |
||||||
|
style={{ paddingRight: '20px', paddingLeft: '20px' }} |
||||||
|
> |
||||||
|
Si |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={6} style={{ textAlign: 'right' }}> |
||||||
|
<Button |
||||||
|
variant='secondary' |
||||||
|
onClick={() => { |
||||||
|
setDialogTabs(false); |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Footer> |
||||||
|
</Modal> |
||||||
|
<Modal |
||||||
|
show={ShowModal} |
||||||
|
onHide={() => { |
||||||
|
setShowModal(false); |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
dialogClassName='modal-50w' |
||||||
|
> |
||||||
|
<Modal.Body> |
||||||
|
<CatProveedores canDelete={true} clasificacion={2} /> |
||||||
|
</Modal.Body> |
||||||
|
</Modal> |
||||||
|
</div> |
||||||
|
); |
||||||
|
}; |
@ -0,0 +1,180 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import { Alert, Button, Col, Modal, Row } from 'react-bootstrap' |
||||||
|
import DataTable from 'react-data-table-component' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import { FaCopy } from 'react-icons/fa' |
||||||
|
import ICorresponsalesRectificaciones from '../../../Interfaces/Corresponsales/ICorresponsalesRectificaciones' |
||||||
|
import RectiDataService from '../../../Services/Corresponsalias/Corresponsales.Trafico.Services' |
||||||
|
import { MsgInformativo } from '../../Utils/Toast/msgInformativo' |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
IDTrafico: number |
||||||
|
changeIdTrafico: (newId: number) => void |
||||||
|
} |
||||||
|
|
||||||
|
export const Rectificaciones: FC<IProps> = (props) => { |
||||||
|
const [DTData, setDTData] = useState<ICorresponsalesRectificaciones[]>([]) |
||||||
|
const [id, setId] = useState(0) |
||||||
|
const [FolioGEMCO, setFolioGEMCO] = useState('') |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msgColor, setMsgColor] = React.useState('primary') |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
const [DialogClone, setDialogClone] = useState(false) |
||||||
|
const [MsgTime, setMsgTime] = useState(3000) |
||||||
|
const dataColumns = [ |
||||||
|
{ |
||||||
|
name: 'id', |
||||||
|
left: true, |
||||||
|
width: '10%', |
||||||
|
selector: (row: ICorresponsalesRectificaciones) => row.id, |
||||||
|
cell: (row: ICorresponsalesRectificaciones) => ( |
||||||
|
<div |
||||||
|
onClick={() => { |
||||||
|
props.changeIdTrafico(row.id) |
||||||
|
}} |
||||||
|
> |
||||||
|
{row.id} |
||||||
|
</div> |
||||||
|
), |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Folio', |
||||||
|
width: '20%', |
||||||
|
selector: (row: ICorresponsalesRectificaciones) => row.folioGemco, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Creado', |
||||||
|
width: '14%', |
||||||
|
selector: (row: ICorresponsalesRectificaciones) => row.fechaRegistro.substring(0, 10), |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Prev', |
||||||
|
center: true, |
||||||
|
width: '20%', |
||||||
|
selector: (row: ICorresponsalesRectificaciones) => row.prevRecti, |
||||||
|
cell: (row: ICorresponsalesRectificaciones) => <div>{row.prevRecti}</div>, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Next', |
||||||
|
center: true, |
||||||
|
width: '20%', |
||||||
|
selector: (row: ICorresponsalesRectificaciones) => row.nextRecti, |
||||||
|
cell: (row: ICorresponsalesRectificaciones) => |
||||||
|
row.nextRecti === 0 ? ( |
||||||
|
<div |
||||||
|
style={{ textAlign: 'center', cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
setId(row.id) |
||||||
|
setFolioGEMCO(row.folioGemco) |
||||||
|
setDialogClone(true) |
||||||
|
}} |
||||||
|
> |
||||||
|
<IconContext.Provider value={{ color: 'blue', size: '25px' }}> |
||||||
|
<FaCopy /> |
||||||
|
</IconContext.Provider> |
||||||
|
</div> |
||||||
|
) : ( |
||||||
|
<div>{row.nextRecti}</div> |
||||||
|
), |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
RectiDataService.GetRectificaciones(props.IDTrafico) |
||||||
|
.then((response) => { |
||||||
|
setDTData(response.data) |
||||||
|
console.log(JSON.stringify(response.data)) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
}, [props.IDTrafico]) |
||||||
|
|
||||||
|
const clonItem = () => { |
||||||
|
RectiDataService.AddRectificacion(id) |
||||||
|
.then((response) => { |
||||||
|
if (response.status == 200) { |
||||||
|
setHeader('Informativo') |
||||||
|
setMsg('La rectificacion se agrego exitosamente') |
||||||
|
setShowMsg(true) |
||||||
|
setDialogClone(false) |
||||||
|
//if (data.id === 0) dispatch(addCorresponsalesFacturas(response.data))
|
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<DataTable |
||||||
|
title='Historial de rectificaciones' |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={dataColumns} |
||||||
|
data={DTData ? DTData : []} |
||||||
|
/> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
time={MsgTime} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
<Modal |
||||||
|
show={DialogClone} |
||||||
|
onHide={() => { |
||||||
|
setDialogClone(false) |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
<Modal.Body> |
||||||
|
<Alert variant='primary'> |
||||||
|
<b>¿Esta seguro de realizar una rectificacion sobre este trafico: [ {FolioGEMCO} ]?</b> |
||||||
|
</Alert> |
||||||
|
</Modal.Body> |
||||||
|
<Modal.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={6} style={{ textAlign: 'left', paddingRight: '100px' }}> |
||||||
|
<Button |
||||||
|
variant='danger' |
||||||
|
onClick={clonItem} |
||||||
|
size='sm' |
||||||
|
style={{ paddingRight: '20px', paddingLeft: '20px' }} |
||||||
|
> |
||||||
|
Si |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
<Col xs={6} style={{ textAlign: 'right' }}> |
||||||
|
<Button |
||||||
|
variant='secondary' |
||||||
|
onClick={() => { |
||||||
|
setDialogClone(false) |
||||||
|
}} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
Cerrar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Modal.Footer> |
||||||
|
</Modal> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,314 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import { Alert, Button, Card, Col, Container, Form, Row } from 'react-bootstrap' |
||||||
|
import ITabulador from '../../../Interfaces/Catalogos/ITabulador' |
||||||
|
import CTabDataService from '../../../Services/Corresponsalias/Corresponsales.Tabuladores.Services' |
||||||
|
import CTabPreDataService from '../../../Services/Corresponsalias/Corresponsales.Precuenta.Services' |
||||||
|
import CTabDetDataService from '../../../Services/Corresponsalias/Corresponsales.Tabuladores.Detalle.Sevices' |
||||||
|
import { MsgInformativo } from '../../Utils/Toast/msgInformativo' |
||||||
|
import DTOConceptos from '../../../DTO/Utils/DTOConceptos' |
||||||
|
import DataTable from 'react-data-table-component' |
||||||
|
import 'react-data-table-component-extensions/dist/index.css' |
||||||
|
import ITabuladorConceptos from '../../../Interfaces/Catalogos/ITabuladorConceptos' |
||||||
|
import { ControlledInput } from '../../Utils/ControlledInput/ControlledInput' |
||||||
|
|
||||||
|
interface IProps { |
||||||
|
IDCliente: number |
||||||
|
IDTabulador: number |
||||||
|
IDTrafico: number |
||||||
|
NombreCliente: string |
||||||
|
closeTabulador: (arg: boolean) => void |
||||||
|
cambiaPrecuenta: (IDPrecuenta: number) => void |
||||||
|
} |
||||||
|
|
||||||
|
interface IselectedRows { |
||||||
|
allSelected: boolean |
||||||
|
selectedCount: number |
||||||
|
selectedRows: any |
||||||
|
} |
||||||
|
|
||||||
|
export const Tabulador: FC<IProps> = (props) => { |
||||||
|
const [IDTabulador, setIDTabulador] = useState(props.IDTabulador) |
||||||
|
const [Concepto, setConcepto] = useState(0) |
||||||
|
const [DetalleConceptos, setDetalleConceptos] = useState<ITabuladorConceptos[]>([]) |
||||||
|
const [CatConceptos, setCatConceptos] = useState<DTOConceptos[]>([]) |
||||||
|
const [Tabuladores, setTabuladores] = useState<ITabulador[]>([]) |
||||||
|
const [AllTabuladores, setAllTabuladores] = useState<ITabulador[]>([]) |
||||||
|
const [Costo, setCosto] = useState('') |
||||||
|
const [header, setHeader] = useState('') |
||||||
|
const [msgColor, setMsgColor] = React.useState('primary') |
||||||
|
const [show, setShowMsg] = useState(false) |
||||||
|
const [msg, setMsg] = useState('') |
||||||
|
|
||||||
|
const columnsConcepts = [ |
||||||
|
{ |
||||||
|
name: 'id', |
||||||
|
width: '10%', |
||||||
|
selector: (row: ITabuladorConceptos) => row.id, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Concepto', |
||||||
|
width: '65%', |
||||||
|
selector: (row: ITabuladorConceptos) => row.concepto, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Costo', |
||||||
|
width: '15%', |
||||||
|
cell: (row: ITabuladorConceptos) => { |
||||||
|
return row.activo === 1 ? ( |
||||||
|
<ControlledInput id={row.id} value={row.costo} disabled={true} postCost={(id, value) => {}} /> |
||||||
|
) : ( |
||||||
|
<ControlledInput id={row.id} value={0} disabled={true} postCost={(id, value) => {}} /> |
||||||
|
) |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Activo', |
||||||
|
width: '10%', |
||||||
|
cell: (row: ITabuladorConceptos) => { |
||||||
|
return ( |
||||||
|
<Form.Group controlId='formBasicCheckbox' style={{ textAlign: 'center' }}> |
||||||
|
<Form.Check |
||||||
|
type='checkbox' |
||||||
|
label='' |
||||||
|
checked={row.activo === 1 ? true : false} |
||||||
|
onClick={() => { |
||||||
|
switchConcept(row.id, 1) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Form.Group> |
||||||
|
) |
||||||
|
}, |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
const columnsTabs = [ |
||||||
|
{ |
||||||
|
name: 'id', |
||||||
|
selector: (row: ITabulador) => row.id, |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'Nombre', |
||||||
|
width: '70%', |
||||||
|
// selector: (row: ITabulador) => row.nombre,
|
||||||
|
cell: (row: ITabulador) => ( |
||||||
|
<div |
||||||
|
style={{ width: '450px', cursor: 'pointer' }} |
||||||
|
onClick={() => { |
||||||
|
setIDTabulador(row.id) |
||||||
|
}} |
||||||
|
> |
||||||
|
{row.nombre} |
||||||
|
</div> |
||||||
|
), |
||||||
|
sortable: true, |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
const switchConcept = (id: number, status: number) => { |
||||||
|
CTabPreDataService.ChangeStatus(id) |
||||||
|
.then((response) => { |
||||||
|
if (response.status === 200) { |
||||||
|
let tmp = DetalleConceptos |
||||||
|
let idx = tmp.findIndex((obj) => obj.id == id) |
||||||
|
tmp[idx].activo = status === 1 ? 0 : 1 |
||||||
|
setDetalleConceptos(tmp) |
||||||
|
setHeader('Confirmacion') |
||||||
|
setMsg(response.data.respuesta) |
||||||
|
setShowMsg(true) |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
// const postCost = (id: number, Cost: number) => {}
|
||||||
|
|
||||||
|
const GetAllTabs = () => { |
||||||
|
CTabDataService.GetByCustomer(props.IDCliente) |
||||||
|
.then((response) => { |
||||||
|
setTabuladores(response.data) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
GetAllTabs() |
||||||
|
}, []) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
CTabPreDataService.GetAll(0, props.IDTrafico) |
||||||
|
.then((response) => { |
||||||
|
console.log('conceptos cargados debido a el tabulador guardado ' + JSON.stringify(response.data)) |
||||||
|
setDetalleConceptos(response.data) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
// console.log(Tabulador)
|
||||||
|
}, [IDTabulador, props]) |
||||||
|
|
||||||
|
const filtraTabulador = (e: any) => { |
||||||
|
if (e.target.value !== '') { |
||||||
|
setTabuladores( |
||||||
|
AllTabuladores.filter(function (el) { |
||||||
|
return el.nombre.toLocaleLowerCase().includes(e.target.value.toLocaleLowerCase()) |
||||||
|
}) |
||||||
|
) |
||||||
|
} else { |
||||||
|
setTabuladores(AllTabuladores) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const saveForm = () => { |
||||||
|
// alert(IDTabulador)
|
||||||
|
CTabPreDataService.Append(IDTabulador, props.IDTrafico) |
||||||
|
.then((response) => { |
||||||
|
setDetalleConceptos(response.data) |
||||||
|
props.cambiaPrecuenta(IDTabulador) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Ocurrio un error: ' + e) |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const addConcept = () => { |
||||||
|
if (IDTabulador === 0) { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Por favor, primero seleccione el tabulador') |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
} |
||||||
|
if (Concepto === 0) { |
||||||
|
setHeader('Error') |
||||||
|
setMsg('Por favor, primero seleccione el concepto') |
||||||
|
setShowMsg(true) |
||||||
|
return |
||||||
|
} |
||||||
|
// postCost(0, 0)
|
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Container fluid> |
||||||
|
<Alert variant='primary'> |
||||||
|
<Row> |
||||||
|
<Col xs={2} style={{ paddingTop: '5px' }}> |
||||||
|
<h5>Cliente: </h5> |
||||||
|
</Col> |
||||||
|
<Col xs={10} style={{ textAlign: 'center' }}> |
||||||
|
<h4>{props.NombreCliente}</h4> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row> |
||||||
|
<Col xs={3}> |
||||||
|
<h6>Tabulador asignado: </h6> |
||||||
|
</Col> |
||||||
|
<Col xs={7}> |
||||||
|
<Form.Control |
||||||
|
as='select' |
||||||
|
value={IDTabulador} |
||||||
|
onChange={(e) => setIDTabulador(parseInt(e.target.value))} |
||||||
|
className='form-select form-select-sm' |
||||||
|
style={{ fontSize: '15px' }} |
||||||
|
> |
||||||
|
<option value='0'>- No tiene tabulador asignado -</option> |
||||||
|
{Tabuladores |
||||||
|
? Tabuladores.map((c) => { |
||||||
|
return <option value={c.id}>{c.nombre}</option> |
||||||
|
}) |
||||||
|
: null} |
||||||
|
</Form.Control> |
||||||
|
</Col> |
||||||
|
<Col xs={1}> |
||||||
|
<Button |
||||||
|
variant='primary' |
||||||
|
size='sm' |
||||||
|
style={{ paddingLeft: '10px', paddingRight: '10px' }} |
||||||
|
onClick={() => saveForm()} |
||||||
|
> |
||||||
|
Guardar |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Alert> |
||||||
|
<Row> |
||||||
|
{/* <Col xs={6}> |
||||||
|
<Card style={{}}> |
||||||
|
<Card.Body> |
||||||
|
<Card.Subtitle className='mb-2 text-muted'> |
||||||
|
<Row> |
||||||
|
<Col xs={2} style={{ paddingTop: '8px' }}> |
||||||
|
Tabulador |
||||||
|
</Col> |
||||||
|
<Col xs={10}> |
||||||
|
<Form.Control |
||||||
|
type='text' |
||||||
|
size='sm' |
||||||
|
placeholder='Busqueda de tabulador...' |
||||||
|
onChange={(e) => { |
||||||
|
filtraTabulador(e) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Card.Subtitle> |
||||||
|
<DataTable |
||||||
|
noHeader |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={columnsTabs} |
||||||
|
data={Tabuladores} |
||||||
|
/> |
||||||
|
</Card.Body> |
||||||
|
</Card> |
||||||
|
</Col> */} |
||||||
|
<Col xs={12}> |
||||||
|
<Card style={{}}> |
||||||
|
<Card.Body> |
||||||
|
<Card.Subtitle className='mb-2 text-muted'></Card.Subtitle> |
||||||
|
<DataTable |
||||||
|
noHeader |
||||||
|
defaultSortFieldId={'id'} |
||||||
|
defaultSortAsc={true} |
||||||
|
pagination |
||||||
|
highlightOnHover |
||||||
|
columns={columnsConcepts} |
||||||
|
data={DetalleConceptos} |
||||||
|
/> |
||||||
|
</Card.Body> |
||||||
|
</Card> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Container> |
||||||
|
<MsgInformativo |
||||||
|
show={show} |
||||||
|
msg={msg} |
||||||
|
header={header} |
||||||
|
msgColor={msgColor} |
||||||
|
closeToast={() => { |
||||||
|
setShowMsg(false) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,42 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import { DashboardCorresponsales } from './DashboardCorresponsales' |
||||||
|
import { DashboardContabilidad } from './DashboardContabilidad' |
||||||
|
import { Col, Container, Row } from 'react-bootstrap' |
||||||
|
import { Heineken1 } from './Heineken1' |
||||||
|
import { DashboardFacturacion } from './DashboardFacturacion' |
||||||
|
|
||||||
|
interface IProps {} |
||||||
|
|
||||||
|
export const Dashboard: FC<IProps> = (props) => { |
||||||
|
const [Depto, setDepto] = useState(() => { |
||||||
|
const stickyValue = window.localStorage.getItem('Departamento') |
||||||
|
return stickyValue !== null ? JSON.parse(stickyValue) : 0 |
||||||
|
}) |
||||||
|
const [User, setUser] = useState(() => { |
||||||
|
const stickyValue = window.localStorage.getItem('User') |
||||||
|
return stickyValue !== null ? JSON.parse(stickyValue) : 0 |
||||||
|
}) |
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<br /> |
||||||
|
<Container> |
||||||
|
<Row xs={1} md={3} className='g-4'> |
||||||
|
{[['Direcccion', 'Sistemas', 'Corresponsalias'].includes(Depto) ? <DashboardCorresponsales /> : ''].map( |
||||||
|
(item) => { |
||||||
|
return <React.Fragment>{item}</React.Fragment> |
||||||
|
} |
||||||
|
)} |
||||||
|
{[['Direcccion', 'Sistemas', 'Contabilidad'].includes(Depto) ? <DashboardContabilidad /> : ''].map((item) => { |
||||||
|
return <React.Fragment>{item}</React.Fragment> |
||||||
|
})} |
||||||
|
{[['Heineken1'].includes(User) ? <Heineken1 /> : ''].map((item) => { |
||||||
|
return <React.Fragment>{item}</React.Fragment> |
||||||
|
})} |
||||||
|
{[['Direcccion', 'Sistemas', 'Facturacion'].includes(Depto) ? <DashboardFacturacion /> : ''].map((item) => { |
||||||
|
return <React.Fragment>{item}</React.Fragment> |
||||||
|
})} |
||||||
|
</Row> |
||||||
|
</Container> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,116 @@ |
|||||||
|
import React, { FC, useEffect, useState } from 'react' |
||||||
|
import { Card, Col, Container, Row } from 'react-bootstrap' |
||||||
|
import { IconContext } from 'react-icons' |
||||||
|
import { BsQuestionOctagonFill } from 'react-icons/bs' |
||||||
|
import { FaCcMastercard, FaFileInvoiceDollar } from 'react-icons/fa' |
||||||
|
import { FcSurvey } from 'react-icons/fc' |
||||||
|
import { Link } from 'react-router-dom' |
||||||
|
import DashboardDataService from '../../Services/Dashboard/Dashboard.Contabilidad.Service' |
||||||
|
|
||||||
|
interface IProps {} |
||||||
|
|
||||||
|
export const DashboardContabilidad: FC<IProps> = (props) => { |
||||||
|
const [CTCTotal, setCTCTotal] = useState(0) // Corresponsales: Traficos terminados listos para contabilidad
|
||||||
|
const [CAPATotal, setCAPATotal] = useState(0) // Corresponsales anticipos pendientes de autorizar
|
||||||
|
const [CuentasComplementariasPedientes, setCuentasComplementariasPendientes] = useState(0) // Corresponsales anticipos pendientes de autorizar
|
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
DashboardDataService.getTotalTraficosPendientesAutorizar(4) |
||||||
|
.then((response) => { |
||||||
|
setCTCTotal(response.data.total) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
return |
||||||
|
}) |
||||||
|
DashboardDataService.getTotalAnticiposPendientes() |
||||||
|
.then((response) => { |
||||||
|
setCAPATotal(response.data.total) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
return |
||||||
|
}) |
||||||
|
DashboardDataService.getTotalCuentasComplementariasPedientes() |
||||||
|
.then((response) => { |
||||||
|
setCuentasComplementariasPendientes(response.data.total) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
return |
||||||
|
}) |
||||||
|
}, []) |
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
<Col> |
||||||
|
<Card style={{ width: '18rem' }}> |
||||||
|
<Card.Header>Contabilidad</Card.Header> |
||||||
|
<Card.Body style={{ paddingBottom: '50px' }}> |
||||||
|
<Card.Title> |
||||||
|
Traficos pendientes |
||||||
|
<br /> |
||||||
|
<br /> |
||||||
|
</Card.Title> |
||||||
|
<Card.Img variant='top' src='' onClick={() => {}} /> |
||||||
|
<div style={{ fontSize: '6em' }} className='text-center'> |
||||||
|
<FcSurvey /> |
||||||
|
{CTCTotal} |
||||||
|
</div> |
||||||
|
</Card.Body> |
||||||
|
<Card.Footer style={{ paddingRight: '5px' }}> |
||||||
|
<Link |
||||||
|
to='../RptCorresponsalesTraficos?proc=2&modo=1' |
||||||
|
style={{ textDecoration: 'none', float: 'right', paddingRight: '10px' }} |
||||||
|
> |
||||||
|
Ver mas... |
||||||
|
</Link> |
||||||
|
</Card.Footer> |
||||||
|
</Card> |
||||||
|
</Col> |
||||||
|
<Col> |
||||||
|
<Card style={{ width: '18rem' }}> |
||||||
|
<Card.Header>Contabilidad </Card.Header> |
||||||
|
<Card.Body style={{ paddingBottom: '50px' }}> |
||||||
|
<Card.Title> Anticipos pendientes de autorizar</Card.Title> |
||||||
|
<Card.Img variant='top' src='' onClick={() => {}} /> |
||||||
|
<div style={{ fontSize: '6em' }} className='text-center'> |
||||||
|
<IconContext.Provider value={{ color: 'orange' }}> |
||||||
|
<FaCcMastercard /> |
||||||
|
</IconContext.Provider> |
||||||
|
{CAPATotal} |
||||||
|
</div> |
||||||
|
</Card.Body> |
||||||
|
<Card.Footer style={{ paddingRight: '5px' }}> |
||||||
|
<Link |
||||||
|
to='../RptCorresponsalesTraficos?proc=2&modo=2' |
||||||
|
style={{ textDecoration: 'none', float: 'right', paddingRight: '10px' }} |
||||||
|
> |
||||||
|
Ver mas... |
||||||
|
</Link> |
||||||
|
</Card.Footer> |
||||||
|
</Card> |
||||||
|
</Col> |
||||||
|
<Col> |
||||||
|
<Card style={{ width: '18rem' }}> |
||||||
|
<Card.Header>Contabilidad </Card.Header> |
||||||
|
<Card.Body style={{ paddingBottom: '50px' }}> |
||||||
|
<Card.Title> Cuentas complementarias pendientes</Card.Title> |
||||||
|
<Card.Img variant='top' src='' onClick={() => {}} /> |
||||||
|
<div style={{ fontSize: '6em' }} className='text-center'> |
||||||
|
<IconContext.Provider value={{ color: '#AAF866' }}> |
||||||
|
<FaFileInvoiceDollar /> |
||||||
|
</IconContext.Provider> |
||||||
|
{CuentasComplementariasPedientes} |
||||||
|
</div> |
||||||
|
</Card.Body> |
||||||
|
<Card.Footer style={{ paddingRight: '5px' }}> |
||||||
|
<Link |
||||||
|
to='../RptCorresponsalesTraficos?proc=2&modo=3' |
||||||
|
style={{ textDecoration: 'none', float: 'right', paddingRight: '10px' }} |
||||||
|
> |
||||||
|
Ver mas... |
||||||
|
</Link> |
||||||
|
</Card.Footer> |
||||||
|
</Card> |
||||||
|
</Col> |
||||||
|
</> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,160 @@ |
|||||||
|
import { FC, useEffect, useState } from 'react'; |
||||||
|
import { Card, Col, Row } from 'react-bootstrap'; |
||||||
|
import { Link } from 'react-router-dom'; |
||||||
|
import DashboardDataService from '../../Services/Dashboard/Dashboard.Corresponsales.Services'; |
||||||
|
import { useNavigate } from 'react-router-dom'; |
||||||
|
import ReactApexChart from 'react-apexcharts'; |
||||||
|
import { ApexOptions } from 'apexcharts'; |
||||||
|
|
||||||
|
interface IProps {} |
||||||
|
|
||||||
|
export const DashboardCorresponsales: FC<IProps> = (props) => { |
||||||
|
let navigate = useNavigate(); |
||||||
|
const [TotalCorresponsales, setTotalCorresponsales] = useState(0); |
||||||
|
const [labels, setlabels] = useState<string[]>([]); |
||||||
|
const [series, setseries] = useState<number[]>([]); |
||||||
|
//const [TipoCambio, setTipoCambio] = useState(0)
|
||||||
|
const [CircleOptions, setCirleOpcions] = useState<ApexOptions>({ |
||||||
|
labels: [ |
||||||
|
'(2) Rechazos para el corresponsal', |
||||||
|
' (0) Rechazados x Contabilidad', |
||||||
|
'(10) Pendientes por terminar', |
||||||
|
], |
||||||
|
colors: ['#EB984E', '#E52626', '#ABEB4E', '#2288D3'], |
||||||
|
legend: { position: 'bottom' }, |
||||||
|
plotOptions: { |
||||||
|
pie: { |
||||||
|
donut: { |
||||||
|
size: '55%', |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
}); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
DashboardDataService.getCorresponsales() |
||||||
|
.then((response) => { |
||||||
|
console.log(response.data); |
||||||
|
let labels: string[] = []; |
||||||
|
let series: number[] = []; |
||||||
|
response.data.forEach((element) => { |
||||||
|
if (element.descripcion.indexOf('Total') === -1) { |
||||||
|
labels.push('(' + element.total + ') : ' + element.descripcion); |
||||||
|
series.push(element.total); |
||||||
|
} else { |
||||||
|
setTotalCorresponsales(element.total); |
||||||
|
} |
||||||
|
}); |
||||||
|
setlabels(labels); |
||||||
|
setseries(series); |
||||||
|
|
||||||
|
setCirleOpcions({ |
||||||
|
labels: labels, |
||||||
|
colors: ['#EB984E', '#E52626', '#ABEB4E'], |
||||||
|
legend: { position: 'bottom' }, |
||||||
|
plotOptions: { |
||||||
|
pie: { |
||||||
|
donut: { |
||||||
|
size: '55%', |
||||||
|
labels: { |
||||||
|
show: true, |
||||||
|
total: { |
||||||
|
showAlways: true, |
||||||
|
show: true, |
||||||
|
fontSize: '15px', |
||||||
|
}, |
||||||
|
value: { |
||||||
|
show: true, |
||||||
|
fontSize: '43px', |
||||||
|
fontWeight: 'bold', |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
}); |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
return; |
||||||
|
}); |
||||||
|
//getTipoCambio(currentDate())
|
||||||
|
}, []); |
||||||
|
|
||||||
|
function ConvertStringToHex(str: string) { |
||||||
|
var arr = []; |
||||||
|
for (var i = 0; i < str.length; i++) { |
||||||
|
arr[i] = ('00' + str.charCodeAt(i).toString(16)).slice(-4); |
||||||
|
} |
||||||
|
return '\\u' + arr.join('\\u'); |
||||||
|
} |
||||||
|
|
||||||
|
function currentDate(): string { |
||||||
|
var today = new Date(); |
||||||
|
var dd = String(today.getDate()).padStart(2, '0'); |
||||||
|
var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
|
||||||
|
var yyyy = today.getFullYear(); |
||||||
|
return yyyy + '-' + mm + '-' + dd; |
||||||
|
} |
||||||
|
|
||||||
|
/* const getTipoCambio = (Fecha: string) => { |
||||||
|
DashboardDataService.getTipoCambio(Fecha) |
||||||
|
.then((response) => { |
||||||
|
setTipoCambio(response.data) |
||||||
|
}) |
||||||
|
.catch((e: Error) => { |
||||||
|
return |
||||||
|
}) |
||||||
|
} */ |
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
<Col> |
||||||
|
<Card style={{ width: '19rem' }}> |
||||||
|
<Card.Header> |
||||||
|
<b>Corresponsales:</b> Traficos pendientes |
||||||
|
</Card.Header> |
||||||
|
<Card.Body style={{ paddingBottom: '10px', paddingTop: '0px' }}> |
||||||
|
<Card.Img variant='top' src='' onClick={() => {}} /> |
||||||
|
{labels ? ( |
||||||
|
<ReactApexChart |
||||||
|
type='donut' |
||||||
|
options={CircleOptions} |
||||||
|
series={series} |
||||||
|
width={250} |
||||||
|
height={500} |
||||||
|
/> |
||||||
|
) : ( |
||||||
|
'' |
||||||
|
)} |
||||||
|
</Card.Body> |
||||||
|
<Card.Footer> |
||||||
|
<Row> |
||||||
|
<Col xs={6} style={{ paddingRight: '5px' }}> |
||||||
|
{/* <Link |
||||||
|
to={`../RptCorresponsalesTraficosHst?proc=0&status=0`} |
||||||
|
style={{ textDecoration: 'none', float: 'right', paddingRight: '10px' }} |
||||||
|
> |
||||||
|
Buscar |
||||||
|
</Link> */} |
||||||
|
{/* <span style={{ fontWeight: 'bold' }}>Tipo cambio: ${TipoCambio}</span> */} |
||||||
|
</Col> |
||||||
|
{/* <Col xs={3}></Col> */} |
||||||
|
<Col xs={6} style={{ paddingRight: '5px' }}> |
||||||
|
<Link |
||||||
|
to={`../RptCorresponsalesTraficos?proc=1&modo=1`} |
||||||
|
style={{ |
||||||
|
textDecoration: 'none', |
||||||
|
float: 'right', |
||||||
|
paddingRight: '10px', |
||||||
|
}} |
||||||
|
> |
||||||
|
Ver mas... |
||||||
|
</Link> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</Card.Footer> |
||||||
|
</Card> |
||||||
|
</Col> |
||||||
|
</> |
||||||
|
); |
||||||
|
}; |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue