Skip to content

Instantly share code, notes, and snippets.

@wmakeev
Last active January 3, 2017 18:29
Show Gist options
  • Save wmakeev/b4cc782e989218f0c2bc to your computer and use it in GitHub Desktop.
Save wmakeev/b4cc782e989218f0c2bc to your computer and use it in GitHub Desktop.
Скрипты МойСклад #moysklad #script
// Разложить папки
(function () {
"use strict"
let folderNameRegEx = /([\w\-]+)\s(\d{2}-\d{2}-\d{2})(?:\s(\S+))?/
let toUpdate = []
let newFolders = client.from('goodFolder')
.filter('parentUuid', '28e1eb74-5884-11e4-90a2-8ecb005341f8') // Новинки
.chain()
.forEach(folder => {
let match = folderNameRegEx.exec(folder.name)
if (match && match.length) {
let folderCode = match[1]
let folderDate = match[2]
let folderFlag = match[3]
if (folderFlag != 'NEW!') {
toUpdate.push({
parentCode: folderCode,
folderDate: folderDate,
folder: folder
})
}
}
})
console.log(toUpdate.map(item => `${item.folder.name} -> ${item.parentCode}`))
let parentsByCode = client.from('goodFolder')
.filter('code', _.uniq(toUpdate.map(item => item.parentCode)))
.chain()
.indexBy(folder => folder.code)
.value()
toUpdate = toUpdate.map(item => {
let folder = item.folder
let parent = parentsByCode[item.parentCode]
folder.parentUuid = parent ? parent.uuid : null
folder.name = item.parentCode + ' ' + item.folderDate
return folder
})
// console.log(toUpdate)
client.save(toUpdate)
})()
// Проверка соответсвия заказа отгрузке
// Все позиции должны совпадать по кол-ву и ценам
// TODO: Кол-во может быть разбито по разным позициям и разным отгрузкам
(function () {
"use strict"
let result = ''
function log (msg) {
result = result + '\n' + msg
}
let lazyBatch = ['Position.good', 'Position.consignment']
let compare = position1 => {
let selectors = ['goodUuid', 'consignmentUuid', 'price.sum']
.map(prop => _.property(prop))
return position2 => selectors.every(sel => sel(position1) === sel(position2))
}
let order = client.load('customerOrder', router.getState().query.id)
let lazy = client.createLazyLoader()
lazy.attach(order, lazyBatch)
let demands = client.from('demand')
.filter('applicable', true)
.uuids(order.demandsUuid)
.chain()
.filter(demand => !demand.deleted)
.value()
lazy.attach(demands, lazyBatch)
let orderPositions = order.getPositions()
let orderPositionsSet = new Set(orderPositions)
let demandsPositions = demands.map(demand => {
let positions = demand.getPositions()
return {
name: demand.name,
positions: positions,
positionsSet: new Set(positions)
}
})
demandsPositions.forEach(pos => {
pos.positions.forEach(position => {
let orderPosition = orderPositions.find(compare(position))
if (orderPosition) {
orderPositionsSet.delete(orderPosition)
pos.positionsSet.delete(position)
}
})
})
let printPos = pos => log(`${pos.consignment.name} ${pos.price.sum / 100} - ${pos.quantity}`)
log('Несовпадения позиций заказа:')
orderPositionsSet.forEach(printPos)
demandsPositions.forEach(data => {
log(`\nНесовпадения позиций в отгрузке ${data.name}:`)
data.positionsSet.forEach(printPos)
})
console.log(result)
})()
// Замена цены закупа минимальной ценой (по базе товаров, если эти цены отличаются)
(function () {
'use strict'
let tools = moysklad.tools
let page = 100
let start = 0
let total = 5000
while (!start || start <= (total + page)) {
console.log('start:', start)
let goods = client.from('good')
.select({
supplierUuid: '49f3ea4c-9a55-4df7-9996-37b098d0b014'
})
.start(start)
.count(page)
.load()
total = goods.total
start += page
let goodsToSave = []
goods.forEach(good => {
if (good.buyPrice !== good.minPrice) {
console.log(`Code: ${good.code} buyPrice: ${good.buyPrice} minPrice: ${good.minPrice}`)
// Цена минимальная
good.buyPrice =
tools.getPrice(good, 'cbf605f6-16e5-11e4-add0-002590a28eca').value =
good.minPrice
goodsToSave.push(good)
}
})
if (goodsToSave.length) {
// console.log(goodsToSave)
client.save(goods)
}
//break
}
})()
// Отчет по продажам за прошлый день
(function () {
"use strict"
let client = require('moysklad-client').createClient()
// Текущее время
let now = new Date()
// Конец прошлого дня
let dayEnd = new Date(now.getFullYear(), now.getMonth(), now.getDate())
// Начало прошлого дня
let dayStart = new Date(dayEnd - 24*60*60*1000)
// Получем все проведенные отгрузки созданные сегодня
let demands = client.from('demand')
.select({
created: { $gt: dayStart, $lt: dayEnd },
applicable: true
})
//.count(2)
.load()
// Убираем удаленные документы
.filter(demand => !demand.deleted)
// Ленивая загрузка связанных товаров для получения имени товара
client.createLazyLoader().attach(demands, ['shipmentOut.good'])
let salesByGood = demands
// Выделяем из всех отгрузок товарные позиции
.reduce((res, demand) =>
res.concat(demand.getPositions().map(pos => {
return {
name: pos.good.name,
quantity: pos.quantity,
price: pos.price.sum / 100,
buyPrice: pos.good.buyPrice / 100
}
})), [])
// Суммируем кол-во проданных товаров
.reduce((res, pos) => {
let report = res[pos.name]
if (report) {
report.quantity += pos.quantity
} else {
res[pos.name] = pos
}
return res
}, {})
// Прибыльность (относительно цены закупа)
let totalProfit = 0
// Строим отчет по продажам
let report = Object.keys(salesByGood)
.map(key => {
let goodReport = salesByGood[key]
let itemProfit =
(goodReport.price - goodReport.buyPrice) * goodReport.quantity
totalProfit += itemProfit
return [
goodReport.name,
goodReport.price,
goodReport.buyPrice,
goodReport.quantity,
Math.round(itemProfit)
].join(';')
}).join('\n')
console.log(report)
console.log('Прибыль за период - ', Math.round(totalProfit))
})()
// Выборка всех замшевых товаров в наличии на сайте
(function() {
'use strict'
const client = moysklad.createClient()
client.options.flowControl = 'async'
const SUPPLIER_UUID = '46bf53af-e826-11e4-7a07-673d0008987c'
const SALES_FOLDER_UUID = '297ea0ca-f197-11e5-7a69-9715001ebade'
// Адаптер для Deffered
function promiseAdapter(eshopPromise) {
return new Promise((resolve,reject) =>
eshopPromise.then(resolve).fail(reject))
}
function clientLoadAsync (query) {
return new Promise((resolve, reject) => {
query.load((err, data) => err ? reject(err) : resolve(data))
})
}
function clientSaveAsync (entities) {
return new Promise((resolve, reject) => {
client.save(entities, (err, data) => err ? reject(err) : resolve(data))
})
}
let eshop = new Entityes.EShopEntities({
name: 'oData',
oDataServiceHost: ESHOP_ODATA_ENDPOINT,
enableJSONP: false
})
eshop.onReady(() => {
co(function * () {
let codes = yield promiseAdapter(
eshop.ProductAttributeValues
.filter(function(item) {
return item.AttributeValueID === attributeValue && item.Product.Available
}, { attributeValue: 14 }) // Замша
.select(`it.ProductID`)
.skip(0).take(1000)
.toArray())
let query = client.from('good')
.select({
code: codes,
supplierUuid: SUPPLIER_UUID
})
let goods = yield clientLoadAsync(query)
goods.forEach(good => { good.parentUuid = SALES_FOLDER_UUID })
return yield clientSaveAsync(goods)
})
.catch(err => console.log(err))
.then((res) => console.log(res))
})
})()
// Поставить выбранные товары в распродажу
(function() {
'use strict'
const { OK, CANCEL } = MODAL_DIALOG_BUTTONS
const tools = moysklad.tools
const client = moysklad.createClient()
client.options.flowControl = 'async'
function clientLoadAsync (query) {
return new Promise((resolve, reject) => {
query.load((err, data) => err ? reject(err) : resolve(data))
})
}
function clientSaveAsync (entities) {
return new Promise((resolve, reject) => {
client.save(entities, (err, data) => err ? reject(err) : resolve(data))
})
}
co(function * () {
let dialogResult = yield showModalForm('Отправить в распродажу', {
supplierDiscount: {
caption: 'Скидка поставщика (руб)',
type: 'number'
},
margin: {
caption: 'Наценка (%)',
type: 'number',
value: 10
}
}, {
buttons: [OK, CANCEL]
})
if (!dialogResult) { return false }
let supplierDiscount = Number.parseInt(dialogResult.supplierDiscount)
if (isNaN(supplierDiscount) || supplierDiscount <= 0) {
throw new Error('Некорректно указана скидка поставщика')
}
let margin = Number.parseInt(dialogResult.margin)
if (isNaN(margin) || margin <= 0) {
throw new Error('Некорректно указана наценка')
}
let codes = Utils.getSelectedGoodsCodes()
if (codes.length === 0) {
throw new Error('Необходимо выбрать товары')
}
let query = client.from('good').filter('code', codes).count(300)
let goods = yield clientLoadAsync(query)
let goodsToUpdate = goods.map(good => {
if (good.name.slice(-6) !== '- sale') {
good.name += ' - sale'
} else {
return null
}
// Закупочная цена
let newBuyPrice = good.buyPrice - (supplierDiscount * 100)
good.minPrice = good.buyPrice = newBuyPrice
// Цена продажи
let goodPrice = tools.getPrice(good, 'e0b4a992-f9c5-44aa-8cee-afa0257a95e6')
// Цена старая
tools.getPrice(good, '9b29b27d-d100-11e3-090f-002590a28eca').value =
goodPrice.value
goodPrice.value = good.salePrice = Math.round(newBuyPrice * (1 + margin / 100))
return good
}).filter(good => good)
if (goodsToUpdate.length) {
clientSaveAsync(goodsToUpdate)
}
return yield showModalDialog('Отправить в распродажу',
`Обновлено ${goodsToUpdate.length} из ${goods.length} товаров`)
})
.then((res) => { if (res) { router.refresh() } })
.catch(err => console.error(err))
})()
// Отправить товар в распродажу
(function () {
"use strict"
let tools = moysklad.tools
let salesFolderUuid = 'acca8044-d95f-11e5-7a69-97110041a0a8'
let posSrcDocumentType = 'purchaseOrder'
let posSrcDocumentUuid = '487beded-d954-11e5-7a69-8f55003fb247'
let newBuyPrice = 1200 * 100
let oldPrice = 1580 * 100
let doc = client.load(posSrcDocumentType, posSrcDocumentUuid)
let goodUuids = tools.getPositions(doc).map(p => p.goodUuid)
let goods = client.from('good').uuids(goodUuids).load()
goods.forEach(good => {
if (good.name.slice(-6) !== '- sale') {
good.name += ' - sale'
}
good.minPrice = good.buyPrice = newBuyPrice
tools.getPrice(good, '9b29b27d-d100-11e3-090f-002590a28eca').value // Цена старая
= oldPrice
tools.getPrice(good, 'e0b4a992-f9c5-44aa-8cee-afa0257a95e6').value // Цена продажи
= good.salePrice = Math.round(newBuyPrice * 1.1)
good.parentUuid = salesFolderUuid
})
client.save(goods)
})()
// Удаление в корзину всех перемещений внутри одного склада
(function () {
"use strict"
const step = 10
function markDelete (entity) {
entity.deleted = new Date()
entity.applicable = false
return entity
}
let moves
let total = 0
do {
moves = client.from('move').sort('moment').select({
applicable: true,
sourceStoreUuid: 'eed5fae7-c949-4258-8e27-69f306d7166c',
targetStoreUuid: 'eed5fae7-c949-4258-8e27-69f306d7166c'
}).count(10).load()
total = moves.total
let trashedMoves = moves.map(markDelete)
console.log(trashedMoves.map(m => m.name), total)
client.save(trashedMoves)
} while (total > 10)
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment