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