taxRate: function (v, obj) { if (R.and( R.path(['invoiceType', 'storeOrderType']), R.path(['invoiceType', 'storeOrderDirection']) )(obj)) { return notEmpty('')(v); } }
function checkObjects(expected, actual) { let checkWithHygiene = cond([ [and(isString, equals('<<hygiene>>')), curry((a, b) => true)], [isObject, curry((a, b) => checkObjects(a, b))], [isArray, curry((a, b) => map(([a, b]) => checkObjects(a, b), zip(a, b)))], [T, curry((a, b) => expect(b).to.be(a))] ]); mapObjIndexed((prop, key, ob) => { let checker = checkWithHygiene(prop); expect(actual).to.have.property(key); checker(actual[key]); }, expected); }
const obj: { [k: string]: number } = { a: 1, c: 2 }; const objMixed: { [k: string]: mixed } = { a: 1, c: "d" }; const os: Array<{ [k: string]: * }> = [{ a: 1, c: "d" }, { b: 2 }]; const str: string = "hello world"; //Logic // TODO: Fix flow issues // const isQueen = _.propEq("rank", "Q"); // const isSpade = _.propEq("suit", "♠︎"); // const isQueenOfSpades = _.allPass([isQueen, isSpade]); //$ExpectError const allp: boolean = isQueenOfSpades(1); const allp1: boolean = isQueenOfSpades({ rank: "Q", suit: "♣︎" }); const a: boolean = _.and(true, true); const a_: (a: boolean) => boolean = _.and(true); const gte = _.anyPass([_.gt, _.equals]); const ge: boolean = gte(3, 2); //$ExpectError const gt10 = x => x > 10; //$ExpectError const even = x => x % 2 === 0; const f = _.both(gt10, even); const b: boolean = f(""); const b_: boolean = f(100); //$ExpectError
const r = require('ramda'); let arr = [undefined]; let result = r.and(...arr) console.log(result);
export const isNumberOfMovesFair = (a, b) => { const bIsValidNumberOfMoves = R.lt(R.subtract(a, b), 2); const aIsValidNumberOfMoves = R.gt(R.subtract(a, b), -2); return R.and(bIsValidNumberOfMoves, aIsValidNumberOfMoves); };
exports.init = function(options) { var updateUrl = options.updateUrl, section = options.section || 'body', form = options.form || section + ' form', $section = $(section), $edit = options.edit ? $(options.edit) : $section.find('.editBtn'), $save = options.save ? $(options.save) : $section.find('.saveBtn'), $cancel = options.cancel ? $(options.cancel) : $section.find('.cancelBtn'), $spinner = options.spinner ? $(options.spinner) : $section.find('.spinner'), displayFields = options.displayFields || section + ' [data-class="display"]', editFields = options.editFields || section + ' [data-class="edit"]', validationFields = options.validationFields || section + ' [data-class="error"]', globalErrorSection = options.globalErrorSection, errorCallback = options.errorCallback || $.noop, onSaveAfter = options.onSaveAfter || _.identity, showSavePending = function (saveIsPending) { $spinner.toggle(saveIsPending); $save.prop('disabled', saveIsPending); $cancel.prop('disabled', saveIsPending); }, editStream = $edit.asEventStream('click').map(editableForm.editStartAction), saveStream = (options.saveStream || $save.asEventStream('click')) .doAction(showSavePending, true) .map('save:start'), externalCancelStream = BU.triggeredObjectStream('cancel'), cancelStream = $cancel.asEventStream('click').map('cancel'), globalCancelStream = cancelStream.merge(externalCancelStream), actionStream = new Bacon.Bus(), editForm = editableForm.init(options), logError = function(error) { console.error("Error uploading to " + updateUrl, error); }, resetCollectionUdfs = function() { // Hide the edit row $("table[data-udf-id] .editrow").hide(); // If there are no 'data' rows on a given table // hide the header and show the placeholder $("table[data-udf-id]").map(function() { var $table = $(this); // If the table has 3 rows they are: // // header, edit row (hidden), placeholder row (hidden) // // This means there is no user data, so // show the placeholder and hide the header if ($table.find('tr').length === 3) { $table.find('.placeholder').show(); $table.find('.headerrow').hide(); } else { // We have some data rows so show the header // and not the placeholder $table.find('.placeholder').hide(); $table.find('.headerrow').show(); } }); }, showCollectionUdfs = function() { // By default collection udfs have their input row // hidden, so show that row $("table[data-udf-id] .editrow").css('display', ''); // The header row may also be hidden if there are no // items so show that as well $("table[data-udf-id] .headerrow").css('display', ''); $("table[data-udf-id] .placeholder").css('display', 'none'); }, getDataToSave = function() { var data = FH.formToDictionary($(form), $(editFields), $(displayFields)); // Extract data for all rows of the collection, // whether entered in this session or pre-existing. $('table[data-udf-name]').map(function() { var $table = $(this); var name = $table.data('udf-name'); var headers = $table.find('tr.headerrow th') .map(function() { return $(this).html(); }); headers = _.compact(headers); data[name] = _.map($table.find('tr[data-value-id]').toArray(), function(row) { var $row = $(row), $tds = $row.find('td'), id = $row.attr('data-value-id'), rowData = _.object(headers, $tds .map(function() { return $.trim($(this).attr('data-value')); })); if (! _.isEmpty(id)) { rowData.id = id; } return rowData; }); }); return data; }, showGlobalErrors = function (errors) { var $globalErrorSection = $(globalErrorSection); if ($globalErrorSection.length > 0) { $globalErrorSection.html(errors.join(',')); $globalErrorSection.show(); } else { console.log('Global error returned from server, ' + 'but no dom element bound from client.', errors); } }, showValidationErrorsInline = function (errors) { $(validationFields).not(globalErrorSection).each(function() { $(this).html(''); }); _.each(errors, function (errorList, fieldName) { var $field = FH.getField($(validationFields), fieldName); if ($field.length > 0) { $field.html(errorList.join(',')); $field.show(); } else { console.log('Field error returned from server, ' + 'but no dom element bound from client.', fieldName, errorList); } }); }, isEditStart = function (action) { return action === 'edit:start'; }, responseStream = saveStream .map(getDataToSave) .flatMapLatest(function (data) { // onSaveBefore is a function that takes form data // and carries out arbitrary, potentially blocking // actions before allowing the save process to // continue. // // the return value of an onSaveBefore callback can be: // * null - for non-blocking side effects and mutation // of the data object // * an eventStream - for blocking side effects, // failure cases and early exits. // // when providing an eventStream as the return value for // onSaveBefore, it should meet the following criteria: // * it should be a stream of data objects. If you are using // eventStreams to block on IO, map them to the `data` // object provided. // * it should pust a new stream value when it's ok to // proceed and block until then. There is no concept // of exiting, just failing to stop blocking. var result = options.onSaveBefore ? options.onSaveBefore(data) : null; if (_.isNull(result) || _.isUndefined(result)) { return Bacon.once(data); } else if (_.isObject(result) && result.hasOwnProperty('takeUntil')) { return result; } else { throw "onSaveBefore returned something other than a stream or null"; } }) .flatMap(function(data) { return Bacon.fromPromise($.ajax({ url: updateUrl, type: 'PUT', contentType: "application/json", data: JSON.stringify(data) })); }), responseErrorStream = responseStream .errors() .mapError(function (e) { showSavePending(false); var result = ('responseJSON' in e) ? e.responseJSON : {}; if ('error' in result) { U.warnDeprecatedErrorMessage(result); result.unstructuredError = result.error; } if (!('unstructuredError' in result)) { // Make sure there's an 'unstructuredError' property // we look for it in the stream that responds to this. // Give it the error object to help with debugging. result.unstructuredError = e; } return result; }), saveOkStream = responseStream.map(function(responseData) { showSavePending(false); return { formData: getDataToSave(), responseData: responseData }; }), validationErrorsStream = responseErrorStream .filter('.fieldErrors') .map('.fieldErrors'), globalErrorsStream = responseErrorStream .filter('.globalErrors') .map('.globalErrors'), unhandledErrorStream = responseErrorStream .filter(R.and(BU.isPropertyUndefined('fieldErrors'), BU.isPropertyUndefined('globalErrors'))) .map('.unstructuredError'), editStartStream = actionStream.filter(isEditStart), inEditModeProperty = actionStream.map(function (event) { return _.contains(eventsLandingInEditMode, event); }) .toProperty() .skipDuplicates(), saveOKFormDataStream = saveOkStream.map('.formData'), eventsLandingInDisplayModeStream = actionStream.filter(_.contains, eventsLandingInDisplayMode), shouldBeInEditModeStream = options.shouldBeInEditModeStream || Bacon.never(), modeChangeStream = shouldBeInEditModeStream .map(function(isInEdit) { return isInEdit ? 'edit:start' : 'cancel'; }); // Prevent default form submission from clicking on buttons or pressing // enter. Event is delegated on window since sometimes <form>s are inserted // into the page via AJAX without reiniting inlineEditForm $(window).on('submit', form, function(event) { event.preventDefault(); }); // Merge the major streams on the page together so that it can centrally // manage the cleanup of ui forms after the change in run mode actionStream.plug(editStream); actionStream.plug(saveStream); actionStream.plug(cancelStream); actionStream.plug(externalCancelStream); actionStream.plug(saveOkStream.map('save:ok')); actionStream.plug(responseErrorStream.map('save:error')); actionStream.plug(modeChangeStream); actionStream.onValue(editForm.hideAndShowElements, editFields, eventsLandingInEditMode); actionStream.onValue(editForm.hideAndShowElements, displayFields, eventsLandingInDisplayMode); actionStream.onValue(editForm.hideAndShowElements, validationFields, ['save:error']); responseStream.onValue(onSaveAfter); globalCancelStream.onValue(showSavePending, false); saveOKFormDataStream.onValue(editForm.formFieldsToDisplayValues); globalErrorsStream.onValue(showGlobalErrors); validationErrorsStream.onValue(showValidationErrorsInline); unhandledErrorStream.onValue(errorCallback); unhandledErrorStream.onValue(logError); editStartStream.onValue(editForm.displayValuesToFormFields); editStartStream.onValue(showCollectionUdfs); eventsLandingInDisplayModeStream.onValue(resetCollectionUdfs); return { // immutable access to all actions actionStream: actionStream.map(_.identity), cancel: externalCancelStream.trigger, saveOkStream: saveOkStream, // TODO: audit all uses of cancelStream, external cancel, and // global cancel stream and merge these streams in the api cancelStream: cancelStream, globalCancelStream: globalCancelStream, inEditModeProperty: inEditModeProperty, showGlobalErrors: showGlobalErrors, showValidationErrorsInline: showValidationErrorsInline, setUpdateUrl: function (url) { updateUrl = url; } }; };
var R = require('ramda'); var res = require('../lib/response'); var req = require('../lib/request'); var actions = [ res.writeHead(200, {'Content-type': 'text/plain'}), R.and(req.urlMatch('/'), res.end('hello world')), R.identity ]; module.exports = R.joint(actions);
var formVf = function ([ errors, obj, typeDropdown, accountTermDropdown, vendorDropdown, purchaserDropdown, storeOrderEditor, invoiceActions ]) { let relateStoreOrders = R.path(['invoiceType', 'storeSubjectType'])(obj); let editable = ~obj.actions.indexOf(invoiceActions.EDIT); return h('form.form', { onsubmit() { $$errors.val({}); co(function *() { if (!dirty(obj)) { $$toast.val({ type: 'info', message: '请做出修改后再提交', }); return; } try { yield invoiceStore.validate(obj); } catch (e) { if (e instanceof ValidationError) { $$errors.val(e.errors); return; } throw e; } try { $$loading.toggle(); let { id } = yield invoiceStore.save(obj); copy = R.clone(obj); $$toast.val({ type: 'success', message: '提交成功', }); !obj.id && page('/invoice/' + id); } catch (e) { console.error(e); } finally { $$loading.toggle(); } }); return false; } }, [ h('.col.col-6', [ !obj.id || editable? field({ key: 'invoiceType', label: '发票类型', input: typeDropdown, errors, required: true }): field({ label: '发票类型', input: h( '.text', (R.find(R.propEq('id', obj.invoiceTypeId))($$invoiceTypes.val()) || {}).name ), }), !obj.id || editable? field({ key: 'date', label: '发票日期', input: h('input', { type: 'date', value: obj.date || moment().format('YYYY-MM-DD'), oninput() { $$obj.patch({ date: this.value }); } }), errors, }): field({ label: '发票日期', input: h('.text', obj.date), }), !obj.id || editable? field({ key: 'number', label: '发票号码', input: h('input', { type: 'text', placeholder: '请输入发票号码', value: obj.number || '', oninput() { $$obj.patch({ number: this.value, }); } }), errors, required: true }): field({ label: '发票号码', input: h('.text', obj.number), }), !obj.id || editable? field({ key: 'accountTermId', label: '会计帐期', input: accountTermDropdown, errors, required: true }): field({ label: '会计账期', input: h('.text', R.path(['accountTerm', 'name'])(obj)) }), R.ifElse( R.path(['invoiceType', 'vendorType']), function () { return !obj.id || editable? field({ key: 'vendorId', label: '实际销售方', input: vendorDropdown, errors, required: true }): field({ label: '实际销售方', input: h('.text', obj.vendor.name), }); }, R.always('') )(obj), R.ifElse( R.path(['invoiceType', 'purchaserType']), function () { return !obj.id || editable? field({ key: 'purchaserId', label: '实际购买方', input: purchaserDropdown, errors, required: true }): field({ label: '实际购买方', input: h('.text', obj.purchaser.name), }); }, R.always('') )(obj), h('.field.inline', [ h('input', { type: 'checkbox', checked: obj.isVat, disabled: obj.id && !editable, onchange() { $$obj.patch({ isVat: this.checked }); } }), h('label', { onclick() { if (!obj.id || editable) { $$obj.patch({ isVat: !obj.isVat }); } } }, '是否是增值税'), ]), h('.field.inline', [ h('label', '备注'), h('textarea', { disabled: obj.id && !editable, rows: 4, onchange() { $$obj.patch({ notes: this.value }); } }, obj.notes || ''), ]), ]), h('.col.col-6', [ !obj.id || editable? field({ key: 'taxRate', label: '税率(百分比)', input: h('input', { value: obj.taxRate || '', oninput() { $$obj.patch({ taxRate: this.value }); } }), errors, required: relateStoreOrders, }): field({ label: '税率(百分比)', input: h('.text', '' + (obj.taxRate || '')), }), !obj.id || editable? relateStoreOrders? h('.field', [ h('label', '相关仓储单据'), storeOrderEditor, ]): void 0: relateStoreOrders? field({ label: '相关仓储单据', input: h('.text', h('ul', obj.storeOrders.map(function (it) { /* eslint-disable max-len */ return h( 'li', `${it.storeSubject.name}-${it.quantity}${it.storeSubject.unit}x${it.unitPrice}元, 共${it.quantity*it.unitPrice}元` ); /* eslint-enable max-len */ }))), }): void 0, field({ key: 'amount', label: '金额', input: h('input', { value: obj.amount, oninput() { $$obj.patch({ amount: this.value }); }, disabled: !editable || relateStoreOrders, }), errors, required: true, }), field({ label: '税额(元)', input: h('.text', R.ifElse( (taxRate, amount) => taxRate && amount, (taxRate, amount) => taxRate * amount / 100 + '', R.always('--') )(obj.taxRate, obj.amount)), }) ]), h('.clearfix'), h('hr'), !obj.id || editable? h('button.primary', '提交'): void 0, h('a.btn.btn-outline', { href: '/invoice-list', }, '返回'), ~obj.actions.indexOf(invoiceActions.AUTHENTICATE)? h('button.primary', { onclick(e) { e.preventDefault(); overlay.show({ type: 'warning', title: '您确认要认证该发票(该操作不可逆)?', message: h('button.btn.btn-outline', { onclick() { overlay.dismiss(); $$loading.val(true); co(function *() { try { $$obj.patch(yield invoiceStore.authenticate(obj.id)); copy = R.clone(obj); $$toast.val({ type: 'success', message: '认证通过!' }); } catch (e) { console.error(e); } finally { $$loading.val(false); } }); return false; } }, '确认') }); return false; } }, '认证'): void 0, ~obj.actions.indexOf(invoiceActions.DELETE)? h('a.btn.btn-outline.ca', { onclick() { overlay.show({ type: 'warning', title: '你确认要删除该条发票?', message: h('button.btn.btn-outline', { onclick() { co(function *() { overlay.dismiss(); $$loading.on(); try { yield invoiceStore.del(obj.id); $$toast.val({ type: 'success', message: '删除成功', }); page('/invoice-list'); } catch (e) { console.error(e); } finally { $$loading.off(); } }); return false; } }, '确认'), }); return false; } }, '删除'): void 0, ~obj.actions.indexOf(invoiceActions.ABORT)? h('a.btn.btn-outline.ca', { onclick() { overlay.show({ type: 'warning', title: '您确认要作废该发票?(该操作不可逆)', message: h('button.btn.btn-outline', { onclick() { overlay.dismiss(); co(function *() { $$loading.on(); try { $$obj.patch(yield invoiceStore.abort(obj.id)); $$toast.val({ type: 'success', message: '操作成功', }); } catch (e) { console.error(e); } finally { $$loading.off(); } }); return false; } }, '确认') }); return false; } }, '作废'): void 0, R.ifElse( R.and(R.prop('isVat'), R.prop('id')), () => h('a.btn.btn-outline', { href: '/voucher?' + object2qs({ amount: obj.amount, voucher_subject_id: obj.invoiceType.relatedVoucherSubjectId, payer_id: obj.purchaserId, recipient_id: obj.vendorId, is_public: 1, }), }, '创建凭证'), () => '' )(obj) ]); };
'use strict'; const R = require('ramda'); const parser = require('./parser'); const isWrappedInCurlyBraces = R.and(R.compose(R.equals('{'), R.head), R.compose(R.equals('}'), R.last)); const removeBracesAndPrependColon = R.compose(R.concat(':'), R.slice(1, -1)); const convertParamToExpressFormat = R.ifElse( isWrappedInCurlyBraces, removeBracesAndPrependColon, R.identity ); const getResource = R.compose(R.join('/'), R.map(convertParamToExpressFormat), R.split('/')); const expressifyPaths = R.over(R.lensProp('path'), getResource); const attachToRouter = R.curry((router, middlewareObj, basePath, route) => { const resource = basePath + route.path; const verb = route.verb; const controllerName = route.controller; const functionName = route.middlewareFunction; if (controllerName && functionName && R.has(functionName, middlewareObj[controllerName])) { console.log(`SETTING UP ROUTE ${resource} ${verb} ${controllerName}.${functionName}`); router[verb](resource, middlewareObj[controllerName][functionName]); } else { console.log(`ERROR setting up ${resource} ${verb}: ${controllerName}.${functionName} not found`); } }); const noEscapeCharsInRoutes = R.compose(R.not, R.any(R.test(/\\/)), R.pluck('path'));
const hasOddDigitsLenghtAndOddIndex = (digitsMod, indexMod) => and(isOdd(digitsMod), isOdd(indexMod))
const hasEvenDigitsLenghtAndEvenIndex = (digitsMod, indexMod) => and(isEven(digitsMod), isEven(indexMod))