diff --git a/app/models/bling_order_item.rb b/app/models/bling_order_item.rb index 02a2e69e..224df46f 100644 --- a/app/models/bling_order_item.rb +++ b/app/models/bling_order_item.rb @@ -33,8 +33,11 @@ class BlingOrderItem < ApplicationRecord # TODO, refactor me separating the tables # There are features hard to implement without this separation. + has_many :items, dependent: :destroy belongs_to :account, optional: true + accepts_nested_attributes_for :items + STORE_ID_NAME_KEY_VALUE = { '204219105' => 'Shein', '203737982' => 'Shopee', @@ -93,7 +96,6 @@ class Status where(store_id: '204061683') } - scope :date_range, lambda { |initial_date, final_date| initial_date = initial_date.try(:to_date).try(:beginning_of_day) final_date = final_date.try(:to_date).try(:end_of_day) @@ -127,4 +129,26 @@ def store_name def value super || 0.0 end + + def synchronize_items + items_attributes = [] + order = Services::Bling::FindOrder.new(id: bling_order_id, order_command: 'find_order', tenant: account.id).call + order['data']['itens'].each do |item| + items_attributes << { + sku: item['codigo'], + unity: item['unidade'], + quantity: item['quantidade'], + discount: item['desconto'], + value: item['valor'], + ipi_tax: item['aliquotaIPI'], + description: item['descricao'], + long_description: item['descricaoDetalhada'], + product_id: item['produto']['id'], + account_id: account.id + } + end + + items.build(items_attributes) + save + end end diff --git a/app/models/item.rb b/app/models/item.rb new file mode 100644 index 00000000..5c2911ab --- /dev/null +++ b/app/models/item.rb @@ -0,0 +1,24 @@ +# == Schema Information +# +# Table name: items +# +# id :bigint not null, primary key +# description :string +# discount :decimal(, ) +# ipi_tax :decimal(, ) +# long_description :string +# quantity :integer +# sku :string +# unity :integer +# value :decimal(, ) +# created_at :datetime not null +# updated_at :datetime not null +# account_id :integer +# bling_order_item_id :bigint +# product_id :bigint +# +class Item < ApplicationRecord + belongs_to :account + belongs_to :product + belongs_to :bling_order_item +end diff --git a/db/migrate/20240103204520_create_items.rb b/db/migrate/20240103204520_create_items.rb new file mode 100644 index 00000000..66ab7196 --- /dev/null +++ b/db/migrate/20240103204520_create_items.rb @@ -0,0 +1,19 @@ +class CreateItems < ActiveRecord::Migration[7.0] + def change + create_table :items do |t| + t.string :sku + t.integer :unity + t.integer :quantity + t.decimal :discount + t.decimal :value + t.decimal :ipi_tax + t.string :description + t.string :long_description + t.bigint :product_id + t.integer :account_id + t.bigint :bling_order_item_id + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 523daf2d..bd2d0a19 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_12_21_234141) do +ActiveRecord::Schema[7.0].define(version: 2024_01_03_204520) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" enable_extension "plpgsql" @@ -211,6 +211,22 @@ t.integer "months", default: 1 end + create_table "items", force: :cascade do |t| + t.string "sku" + t.integer "unity" + t.integer "quantity" + t.decimal "discount" + t.decimal "value" + t.decimal "ipi_tax" + t.string "description" + t.string "long_description" + t.bigint "product_id" + t.integer "account_id" + t.bigint "bling_order_item_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "post_data", force: :cascade do |t| t.string "client_name" t.string "cep" diff --git a/spec/models/bling_order_item_spec.rb b/spec/models/bling_order_item_spec.rb index 09ae8d41..3771232f 100644 --- a/spec/models/bling_order_item_spec.rb +++ b/spec/models/bling_order_item_spec.rb @@ -32,6 +32,36 @@ require 'rails_helper' RSpec.describe BlingOrderItem, type: :model do + describe 'associations' do + it { is_expected.to have_many(:items).dependent(:destroy) } + end + + describe 'nested attributes' do + it { is_expected.to accept_nested_attributes_for(:items) } + end + + describe '#synchronize_items' do + subject(:synchronize_items) { order.synchronize_items } + + include_context 'with bling token' + + let(:order) { FactoryBot.create(:bling_order_item, bling_order_id: 19_178_587_026, account_id: user.account.id) } + + before do + VCR.use_cassette('find_order', erb: true) do + synchronize_items + end + end + + it 'counts 1 item' do + expect(order.items.length).to eq(1) + end + + it 'has quantity 1' do + expect(order.items.first.quantity).to eq(1) + end + end + describe '#store_name' do it 'has name' do subject.store_id = '204219105' diff --git a/spec/models/item_spec.rb b/spec/models/item_spec.rb new file mode 100644 index 00000000..dd0f56bd --- /dev/null +++ b/spec/models/item_spec.rb @@ -0,0 +1,35 @@ +# == Schema Information +# +# Table name: items +# +# id :bigint not null, primary key +# description :string +# discount :decimal(, ) +# ipi_tax :decimal(, ) +# long_description :string +# quantity :integer +# sku :string +# unity :integer +# value :decimal(, ) +# created_at :datetime not null +# updated_at :datetime not null +# account_id :integer +# bling_order_item_id :bigint +# product_id :bigint +# +require 'rails_helper' + +RSpec.describe Item, type: :model do + describe 'associations' do + it { is_expected.to belong_to(:product) } + it { is_expected.to belong_to(:account) } + it { is_expected.to belong_to(:bling_order_item) } + end + + describe 'db columns' do + it { is_expected.to have_db_column(:sku) } + it { is_expected.to have_db_column(:unity) } + it { is_expected.to have_db_column(:value) } + it { is_expected.to have_db_column(:quantity) } + end +end diff --git a/spec/vcr/find_order.yml b/spec/vcr/find_order.yml new file mode 100644 index 00000000..dc805dad --- /dev/null +++ b/spec/vcr/find_order.yml @@ -0,0 +1,69 @@ +--- +http_interactions: +- request: + method: get + uri: https://www.bling.com.br/Api/v3/pedidos/vendas/19178587026 + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Authorization: + - Bearer <%= ENV['ACCESS_TOKEN'] %> + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + User-Agent: + - Ruby + Host: + - www.bling.com.br + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 03 Jan 2024 22:40:48 GMT + Content-Type: + - application/json + Content-Length: + - '1510' + Connection: + - keep-alive + Server-Timing: + - intid;desc=dd79552b3cd65386 + Set-Cookie: + - PHPSESSID=4dv7bciha4iqkmelkfjrj6mdsk; path=/; secure; HttpOnly + - PHPSESSID=ovsp6s05mqako6iufqp57uip53; path=/; secure; HttpOnly + Expires: + - Thu, 19 Nov 1981 08:52:00 GMT + Cache-Control: + - no-cache, public, must-revalidate, max-age=2592000 + Pragma: + - no-cache + Vary: + - Accept-Encoding + Cf-Cache-Status: + - DYNAMIC + Strict-Transport-Security: + - max-age=31536000 + Referrer-Policy: + - strict-origin-when-cross-origin + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + Server: + - cloudflare + Cf-Ray: + - 83febed9cdd126a4-GIG + body: + encoding: ASCII-8BIT + string: '{"data":{"id":19178587026,"numero":49911,"numeroLoja":"GSHNA331F00N1B7","data":"2023-11-22","dataSaida":"2023-11-22","dataPrevista":"0000-00-00","totalProdutos":40.7,"total":40.7,"contato":{"id":16438305363,"nome":"Faker + Name Souza","tipoPessoa":"F","numeroDocumento":"999.999.999-99"},"situacao":{"id":12,"valor":2},"loja":{"id":204219105},"numeroPedidoCompra":"","outrasDespesas":0,"observacoes":"","observacoesInternas":"","desconto":{"valor":0,"unidade":"REAL"},"categoria":{"id":0},"notaFiscal":{"id":19184511286},"tributacao":{"totalICMS":0,"totalIPI":0},"itens":[{"id":16347285097,"codigo":"VEST-LONG-TOP-SAI-FEND-BRANCO-P","unidade":"1","quantidade":1,"desconto":0,"valor":40.7,"aliquotaIPI":0,"descricao":"Vestido + LONGO top + saia fenda Cor:Branco;Tamanho:P","descricaoDetalhada":"","produto":{"id":15973680258},"comissao":{"base":40.7,"aliquota":0,"valor":0}}],"parcelas":[{"id":16547387358,"dataVencimento":"2023-12-22","valor":40.7,"observacoes":"","formaPagamento":{"id":1135275}}],"transporte":{"fretePorConta":0,"frete":0,"quantidadeVolumes":0,"pesoBruto":0,"prazoEntrega":0,"contato":{"id":0,"nome":""},"etiqueta":{"nome":"Faker + Name Souza","endereco":"Avenida Sete de Setembro- de 401 a 899 - lado mpar","numero":"Center + sho","complemento":"","municipio":"Ararangu\u00e1","uf":"SC","cep":"88901004","bairro":"Cidade + Alta","nomePais":""},"volumes":[]},"vendedor":{"id":0},"intermediador":{"cnpj":"","nomeUsuario":""},"taxas":{"taxaComissao":0,"custoFrete":0,"valorBase":0}}}' + recorded_at: Wed, 03 Jan 2024 22:40:48 GMT +recorded_with: VCR 6.2.0