SaveProduct.vue 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. <template>
  2. <div style="margin: 30px">
  3. <q-field :error="Boolean(error.product_type)"
  4. :error-label="error.product_type"
  5. :label="texts.save_product_type">
  6. <div v-if="product_type_selected" class="row">
  7. <span v-if="product_type==''"> {{ texts.save_no_product_selected }}</span>
  8. <span v-else>{{ product_type }}</span>
  9. <q-btn @click="product_type_selected=false" class="bg-primary">
  10. {{ texts.save_change }}
  11. </q-btn>
  12. </div>
  13. <div v-else>
  14. <q-field :label="texts.save_filter_by">
  15. <q-input label="Name" v-model="product_type_filter"/>
  16. </q-field>
  17. <q-tree
  18. :nodes="product_types"
  19. node-key="name"
  20. color="red"
  21. accordion
  22. default-expand-all
  23. :filter="product_type_filter"
  24. :selected.sync="selected_product_type"
  25. >
  26. <div slot="default-header" slot-scope="prop" class="row item-center">
  27. <div class="text-weight-bold text-primary"@click="product_type_clicked(prop.node)">
  28. {{ prop.node.label }}
  29. </div>
  30. </div>
  31. </q-tree>
  32. </div>
  33. </q-field>
  34. <q-field
  35. :error="Boolean(error.name)"
  36. :error-label="error.name"
  37. :label="texts.save_name">
  38. <q-input label="Name" v-model="product_data.name"/>
  39. </q-field>
  40. <q-field :label="texts.save_is_generic">
  41. <q-toggle type="boolean" v-model="product_data.is_generic"/>
  42. </q-field>
  43. <q-field :label="texts.save_weight">
  44. <q-slider :min="0" :max="1000"
  45. v-model="product_data.weight" label square
  46. label-always/>
  47. <q-select :options="weight_units" v-model="product_data.weight_unit"/>
  48. </q-field>
  49. <q-field
  50. :error="Boolean(error.description)"
  51. :error-label="error.description"
  52. :label="texts.save_description">
  53. <q-input v-model="product_data.description"/>
  54. </q-field>
  55. <q-field :label="texts.save_packaging_materials">
  56. <div>
  57. <span v-if="packaging_materials.length==0"> {{ texts.save_no_packaging_selected }} </span>
  58. <span v-else>
  59. <q-list striped>
  60. <q-item v-for="packaging_material,index in packaging_materials">
  61. <q-item-main>
  62. <q-item-tile>
  63. {{packaging_material.label}}
  64. </q-item-tile>
  65. <q-item-tile>
  66. <q-field :label="texts.save_weight">
  67. <q-slider :min="0" :max="1000"
  68. v-model="packaging_material.weight" label square
  69. label-always/>
  70. <q-select :options="weight_units" v-model="packaging_material.weight_unit"/>
  71. </q-field>
  72. </q-item-tile>
  73. </q-item-main>
  74. <q-item-side>
  75. <q-btn
  76. @click="remove_packaging_material(packaging_material)">{{texts.save_remove}}</q-btn>
  77. </q-item-side>
  78. </q-item>
  79. </q-list>
  80. </span>
  81. <q-btn @click="packaging_selected=false" class="bg-primary">
  82. {{ texts.save_add }}
  83. </q-btn>
  84. </div>
  85. <div v-if="!packaging_selected">
  86. <q-field :label="texts.save_filter_by">
  87. <q-input label="Name" v-model="packaging_material_filter"/>
  88. </q-field>
  89. <q-tree
  90. :nodes="packagings"
  91. :filter="packaging_material_filter"
  92. default-expand-all
  93. node-key="id"
  94. color="red"
  95. accordion
  96. :selected.sync="selected_packaging"
  97. >
  98. <div slot="default-header" slot-scope="prop" class="row item-center">
  99. <div class="text-weight-bold text-primary"@click="packaging_clicked(prop.node)">
  100. {{ prop.node.label }}
  101. </div>
  102. </div>
  103. </q-tree>
  104. </div>
  105. </q-field>
  106. <div class="flexrow">
  107. <q-btn :loading="save_loading" @click="save()">{{texts.save_save}}</q-btn>
  108. </div>
  109. </div>
  110. </template>
  111. <script>
  112. var api = require('../api.js')
  113. var utils = require('../utils.js')
  114. import {
  115. QCard,
  116. QLayout,
  117. QToolbar,
  118. QToolbarTitle,
  119. QBtn,
  120. QIcon,
  121. QList,
  122. QListHeader,
  123. QItem,
  124. QItemSide,
  125. QItemMain,
  126. QItemTile,
  127. QSlider,
  128. QInput,
  129. QField,
  130. QToggle,
  131. QTree,
  132. QSelect,
  133. Notify
  134. } from 'quasar'
  135. export default {
  136. name: 'index',
  137. components: {
  138. QCard,
  139. QLayout,
  140. QToolbar,
  141. QToolbarTitle,
  142. QBtn,
  143. QIcon,
  144. QList,
  145. QListHeader,
  146. QItem,
  147. QItemSide,
  148. QItemTile,
  149. QItemMain,
  150. QSlider,
  151. QInput,
  152. QField,
  153. QToggle,
  154. QTree,
  155. QSelect
  156. },
  157. data () {
  158. return {
  159. products: [
  160. {name: 'hello'}
  161. ],
  162. weight_units: [],
  163. length_units: [],
  164. data: [],
  165. selected_product_type: null,
  166. api: api,
  167. current_hier_index: 1,
  168. disable_save: true,
  169. product_type: '',
  170. product_type_selected: true,
  171. packaging_material_filter: '',
  172. packaging: '',
  173. packagings: [],
  174. packaging_materials: [],
  175. selected_packaging: null,
  176. packaging_selected: true,
  177. packaging: [],
  178. product_type_filter: '',
  179. product_types: [{
  180. name: 'hi',
  181. children: []
  182. }],
  183. save_loading: false,
  184. product_data: {
  185. weight_unit: 2,
  186. weight: 110,
  187. description: '',
  188. product_type: 0,
  189. name: '',
  190. length: 0,
  191. width: 0,
  192. height: 0,
  193. EAN_code: 0,
  194. is_generic: false
  195. },
  196. texts: {},
  197. error: {}
  198. }
  199. },
  200. methods: {
  201. packaging_clicked: function (node) {
  202. if(node.id === 1 || node.id === 2){
  203. return false
  204. }
  205. this.product_data.packaging_material = node.id
  206. this.packaging = node.label
  207. this.packaging_selected = true
  208. if (this.packaging_materials.indexOf(node)==-1) {
  209. node.weight = 0
  210. node.weight_unit = this.product_data.weight_unit
  211. this.packaging_materials.push(node)
  212. }
  213. else {
  214. }
  215. },
  216. remove_packaging_material: function (node) {
  217. this.packaging_materials.pop(node)
  218. },
  219. product_type_clicked: function (node) {
  220. if(node.id !== 1){
  221. this.product_data.product_type = node.id
  222. this.product_type = node.label
  223. this.product_type_selected = true
  224. }
  225. },
  226. save_product: function () {
  227. var self = this
  228. self.save_loading = true
  229. return new Promise((resolve, reject) => {
  230. [{name: 'name', default:'none'}, {name: 'description', default:
  231. 'none'}, {name: 'product_type', default: 1}].forEach(data => {
  232. console.log(data)
  233. if (!window.Boolean(self.product_data[data.name])) {
  234. self.product_data[data.name] = data.default
  235. console.log(data.name)
  236. }
  237. })
  238. api.create('scanapp/{LANG}/products/', this.product_data)
  239. .then((data) => {
  240. self.packaging_materials.forEach(packaging_materialsq => {
  241. var bom_data = {product: data.data.id}
  242. bom_data.product_type = packaging_materialsq.id
  243. bom_data.weight = packaging_materialsq.weight
  244. api.create('scanapp/{LANG}/bom/', bom_data)
  245. })
  246. var n = 0
  247. window.images.forEach((image) => {
  248. api.uploadImage(data.data.id, data.data.name + n, image)
  249. .then(data => {
  250. n += 1
  251. if (window.images.length === n) {
  252. Notify.create(self.texts.save_notify_saved)
  253. resolve(data)
  254. }
  255. })
  256. })
  257. })
  258. .catch(err => {
  259. self.save_loading = false
  260. if (err.response.status == 400) {
  261. var error = err.response.data
  262. for(var field in error) {
  263. if(error[field]){
  264. self.error[field] = error[field][0]
  265. }
  266. }
  267. }
  268. })
  269. })
  270. },
  271. save: function () {
  272. this.save_product().then(() => { this.$router.push('/') })
  273. },
  274. save_and_continue: function () {
  275. this.save_product().then(() => { this.$router.push('new') })
  276. }
  277. },
  278. mounted () {
  279. window.me = this
  280. var self = this
  281. var index = 1
  282. utils.setTexts(this)
  283. self.product_data.EAN_code = window.sessionStorage.getItem('barcode_id')
  284. db.getData('scanapp/{LANG}/product_hier/2/.detail').then(function (data) {
  285. self.packagings = []
  286. self.packagings.push(data)
  287. })
  288. db.getData('scanapp/{LANG}/product_hier/1/.detail')
  289. .then(data => {
  290. self.product_types = []
  291. self.product_types.push(data)
  292. })
  293. db.getData('language/{LANG}/weight/.list').then(data => {
  294. self.weight_units = []
  295. data.forEach(unit => {
  296. unit.label = unit.name
  297. unit.value = unit.id
  298. self.weight_units.push(unit)
  299. })
  300. self.product_data.weight_unit = data[0].id
  301. })
  302. db.getData('language/{LANG}/length/.list').then(data => {
  303. self.length_units = []
  304. data.forEach(unit => {
  305. unit.label = unit.name
  306. unit.value = unit.name
  307. self.length_units.push(unit)
  308. })
  309. self.product_data.length_unit = data[0].name
  310. })
  311. },
  312. beforeDestroy () {
  313. },
  314. }
  315. </script>
  316. <style lang="stylus" scoped>
  317. @import '~variables'
  318. .div
  319. display: flex
  320. flex-direction: column
  321. align-items: left
  322. .flexrow
  323. flex-direction: row
  324. .primary
  325. background-color: $blue
  326. </style>